home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Tools / Languages / MacGambit 2.0 / sources2 / Runtime (.scm & .s) / _kernel.s < prev    next >
Encoding:
Text File  |  1992-10-02  |  124.3 KB  |  4,778 lines  |  [TEXT/gamI]

  1. /*---------------------------------------------------------------------------*/
  2.  
  3. /* file: "_kernel.s" */
  4.  
  5. /*-----------------------------------------------------------------------------
  6.  
  7. GAMBIT kernel.
  8.  
  9. This file should be assembled with 'AS' to produce '_kernel.O'.
  10. 'kernel.O' is the first object file to be loaded into the system.  The
  11. first object in the file (which must be a procedure) is responsible
  12. for setting up the runtime context and running all the other modules
  13. that were loaded.  This procedure is special because it uses the C
  14. calling convention.
  15.  
  16. -----------------------------------------------------------------------------*/
  17.  
  18.  
  19. /* Main parameters: */
  20.  
  21.  
  22. /* Define MIN_C_CONTEXT if C's context is kept only in A5, A6 and SP */
  23.  
  24. #define MIN_C_CONTEXT
  25.  
  26.  
  27. /* Define DETERMINE_IS_STRICT if 'determine!' should touch its second arg */
  28.  
  29. #define DETERMINE_IS_STRICT
  30.  
  31. #define LIGITIMACY
  32.  
  33.  
  34. /* Define MESSAGE_PASSING_STEAL if tasks are stolen with message passing */
  35. /* protocol (otherwise, shared memory protocol is used) */
  36.  
  37. #define MESSAGE_PASSING_STEAL
  38.  
  39.  
  40. /* Define SYNCHRONOUS_STEAL if thief processor waits for reply from victim */
  41.  
  42. #define SYNCHRONOUS_STEAL
  43.  
  44.  
  45. /* Define MAINTAIN_TASK_STATUS if the status of the tasks should be updated. */
  46. /* There are 4 possible states: READY to run (status=pointer to queue entry),*/
  47. /* RUNNING (status=pointer to processor state), WAITING (status=null) and */
  48. /* DEAD (status=false). */
  49.  
  50. #define MAINTAIN_TASK_STATUS
  51.  
  52.  
  53. /* MAX_FRAME_CHUNK_SIZE is the maximum number of slots in a stack frame */
  54. /* chunk (i.e. a group of contiguous stack frames) */
  55.  
  56. #define MAX_FRAME_CHUNK_SIZE 25
  57. #define MAX_FRAME_CHUNK_SIZEzzz 1024
  58.  
  59.  
  60. /* MAX_TASK_FRAME_CHUNK_SIZE is the maximum number of slots in a stack frame */
  61. /* chunk which contains lazy tasks.  MIN_VICTIM_TASKS is the minimum number */
  62. /* of lazy tasks to leave the victim when there is a steal of more than one */
  63. /* task. */
  64.  
  65. #define MAX_TASK_FRAME_CHUNK_SIZEzzz 25
  66. #define MIN_VICTIM_TASKSzzz 20
  67. #define MAX_TASK_FRAME_CHUNK_SIZE 25
  68. #define MIN_VICTIM_TASKS 20
  69.  
  70.  
  71. /* Interrupt checking latencies (1 = soonest possible) */
  72.  
  73. #define INTR_LATENCY_AFTER_STEAL 5
  74.  
  75.  
  76. /*---------------------------------------------------------------------------*/
  77.  
  78.  
  79. /* DYN_ENV_FS is the size of a dynamic environment frame */
  80.  
  81. #define DYN_ENV_FS 2
  82.  
  83.  
  84. /*---------------------------------------------------------------------------*/
  85.  
  86.  
  87. /* String concatenation depends on style of preprocessing... */
  88. #ifdef __STDC__
  89. #define MAKE_LBL(x,y)y##__##x
  90. #else
  91. #define QUOTE(x)x
  92. #define MAKE_LBL(x,y)QUOTE(QUOTE(y)__)x
  93. #endif
  94.  
  95.  
  96. #ifdef hpux
  97.  
  98. /* HPUX assembler definitions... */
  99.  
  100. #define OBJECT_FILE_BEGIN _object_file_begin: global _object_file_begin
  101. #define OBJECT_FILE_END _object_file_end: global _object_file_end
  102.  
  103. #define DISP(r,n)    n(r)
  104. #define INXW(r,i,n)  n(r,i.w)
  105. #define PC_IND(lab)  LBL(lab)(%pc)
  106. #define ALIGN2       lalign 2
  107. #define ALIGN4       lalign 4
  108. #define ALIGN8       lalign 8
  109. #define SET(a,b)     set a,b
  110. #define CONST(n)     LBL($consts)+(n*4)(%pc)
  111. #define REG(x)       %x
  112. #define IMM(x)       &x
  113. #define PINC(r)      (r)+
  114. #define PDEC(r)      -(r)
  115. #define IND(r)       (r)
  116. #define BYTE         byte
  117. #define WORD         short
  118. #define LONG         long
  119. #define ASCIZ        asciz
  120. #define movb         move.b
  121. #define movw         move.w
  122. #define movl         move.l
  123. #define extl         ext.l
  124. #define addw         add.w
  125. #define addl         add.l
  126. #define addqw        addq.w
  127. #define addql        addq.l
  128. #define subw         sub.w
  129. #define subl         sub.l
  130. #define subqw        subq.w
  131. #define subql        subq.l
  132. #define negl         neg.l
  133. #define clrb         clr.b
  134. #define clrl         clr.l
  135. #define muluw        mulu.w
  136. #define notw         not.w
  137. #define andw         and.w
  138. #define andl         and.l
  139. #define aslw         asl.w
  140. #define asll         asl.l
  141. #define asrw         asr.w
  142. #define asrl         asr.l
  143. #define lsrw         lsr.w
  144. #define lsrl         lsr.l
  145. #define tstw         tst.w
  146. #define tstl         tst.l
  147. #define CMPW(x,y)    cmp.w y,x
  148. #define CMPL(x,y)    cmp.l y,x
  149. #define DBRA(r,lab)  dbra r,LBL(lab)
  150. #define BRAS(lab)    bra.b LBL(lab)
  151. #define BEQS(lab)    beq.b LBL(lab)
  152. #define BEQW(lab)    beq.w LBL(lab)
  153. #define BNES(lab)    bne.b LBL(lab)
  154. #define BNEW(lab)    bne.w LBL(lab)
  155. #define BMIS(lab)    bmi.b LBL(lab)
  156. #define BMIW(lab)    bmi.w LBL(lab)
  157. #define BPLS(lab)    bpl.b LBL(lab)
  158. #define BPLW(lab)    bpl.w LBL(lab)
  159. #define BLES(lab)    ble.b LBL(lab)
  160. #define BLEW(lab)    ble.w LBL(lab)
  161. #define BGES(lab)    bge.b LBL(lab)
  162. #define BCCS(lab)    bcc.b LBL(lab)
  163. #define BCCW(lab)    bcc.w LBL(lab)
  164. #define BCSS(lab)    bcs.b LBL(lab)
  165. #define BCSW(lab)    bcs.w LBL(lab)
  166. #define BLSS(lab)    bls.b LBL(lab)
  167. #define BHIS(lab)    bhi.b LBL(lab)
  168. #define BGTS(lab)    bgt.b LBL(lab)
  169. #define BGTW(lab)    bgt.w LBL(lab)
  170. #define BLTS(lab)    blt.b LBL(lab)
  171. #define BRAW(lab)    bra.w LBL(lab)
  172. #define BSRW(lab)    bsr.w LBL(lab)
  173.  
  174. #define fmovel       fmov.l
  175. #define FPCR         %fpcr
  176. #define FPSR         %fpsr
  177.  
  178. #else
  179.  
  180. /* SUN3 assembler definitions... */
  181.  
  182. #define OBJECT_FILE_BEGIN _object_file_begin: .globl _object_file_begin
  183. #define OBJECT_FILE_END _object_file_end: .globl _object_file_end
  184.  
  185. #define DISP(r,n)    r@(n:w)
  186. #define INXW(r,i,n)  r@(n:w,i:w)
  187. #define PC_IND(lab)  pc@(-2-(.-LBL(lab)):w)
  188. #define ALIGN2       .even
  189. #define ALIGN4       .=(.-_object_file_begin+3)/4*4
  190. #define ALIGN8       .=(.-_object_file_begin+7)/8*8
  191. #define SET(a,b)     a = b
  192. #define CONST(n)     pc@((n*4)-2-(.-LBL($consts)):w)
  193. #define REG(r)       r
  194. #define IMM(x)       #x
  195. #define PINC(r)      r@+
  196. #define PDEC(r)      r@-
  197. #define IND(r)       r@
  198. #define BYTE         .byte
  199. #define WORD         .word
  200. #define LONG         .long
  201. #define ASCIZ        .asciz
  202. #define muluw        mulu
  203. #define CMPW(x,y)    cmpw x,y
  204. #define CMPL(x,y)    cmpl x,y
  205. #define DBRA(r,lab)  dbra r,LBL(lab)
  206. #define BRAS(lab)    BYTE 0x60,LBL(lab)-.-2
  207. #define BEQS(lab)    BYTE 0x67,LBL(lab)-.-2
  208. #define BEQW(lab)    WORD 0x6700,LBL(lab)-.-2
  209. #define BNES(lab)    BYTE 0x66,LBL(lab)-.-2
  210. #define BNEW(lab)    WORD 0x6600,LBL(lab)-.-2
  211. #define BMIS(lab)    BYTE 0x6b,LBL(lab)-.-2
  212. #define BMIW(lab)    WORD 0x6b00,LBL(lab)-.-2
  213. #define BPLS(lab)    BYTE 0x6a,LBL(lab)-.-2
  214. #define BPLW(lab)    WORD 0x6a00,LBL(lab)-.-2
  215. #define BLES(lab)    BYTE 0x6f,LBL(lab)-.-2
  216. #define BLEW(lab)    WORD 0x6f00,LBL(lab)-.-2
  217. #define BGES(lab)    BYTE 0x6c,LBL(lab)-.-2
  218. #define BCCS(lab)    BYTE 0x64,LBL(lab)-.-2
  219. #define BCCW(lab)    WORD 0x6400,LBL(lab)-.-2
  220. #define BCSS(lab)    BYTE 0x65,LBL(lab)-.-2
  221. #define BCSW(lab)    WORD 0x6500,LBL(lab)-.-2
  222. #define BLSS(lab)    BYTE 0x63,LBL(lab)-.-2
  223. #define BHIS(lab)    BYTE 0x62,LBL(lab)-.-2
  224. #define BGTS(lab)    BYTE 0x6e,LBL(lab)-.-2
  225. #define BGTW(lab)    WORD 0x6e00,LBL(lab)-.-2
  226. #define BLTS(lab)    BYTE 0x6d,LBL(lab)-.-2
  227. #define BRAW(lab)    WORD 0x6000,LBL(lab)-.-2
  228. #define BSRW(lab)    WORD 0x6100,LBL(lab)-.-2
  229.  
  230. #define FPCR         fpcr
  231. #define FPSR         fpsr
  232.  
  233.     .data
  234.  
  235. #endif
  236.  
  237.  
  238. /* General definitions... */
  239.  
  240.  
  241. #define PRIMITIVE(name)                            \
  242. %NEWLINE%    LONG PRIM_PROC+(INDEX_MASK*8)                \
  243. %NEWLINE%    ASCIZ name                        \
  244. %NEWLINE%    ALIGN2
  245.  
  246. #define BEGIN(name)                            \
  247. %NEWLINE%    LONG PRIM_PROC_PREFIX                    \
  248. %NEWLINE%    WORD INDEX_MASK                        \
  249. %NEWLINE%    ASCIZ name                        \
  250. %NEWLINE%    ALIGN2                            \
  251. %NEWLINE%    WORD LBL($header)                    \
  252. %NEWLINE%    ALIGN8                            \
  253. %NEWLINE%    WORD LBL($code_len_tag)                    \
  254. %NEWLINE%LBL($entry):
  255.  
  256. #define CONSTS(n)                            \
  257. %NEWLINE%    ALIGN4                            \
  258. %NEWLINE%LBL($consts):                            \
  259. %NEWLINE%    WORD END_OF_CODE_TAG                    \
  260. %NEWLINE%    SET(LBL($nb_consts),n+2)
  261.     
  262. #define END                                \
  263. %NEWLINE%    LONG SCM_false                        \
  264. %NEWLINE%    LONG LBL($nb_consts)*8                    \
  265. %NEWLINE%    SET(LBL($code_len),LBL($consts)-LBL($entry))        \
  266. %NEWLINE%    SET(LBL($code_len_tag),LBL($code_len)/2)        \
  267. %NEWLINE%    SET(LBL($header),HEADER(LBL($nb_consts)*4)+LBL($code_len)-2)
  268.  
  269. #define HEADER(l)    ((l)+0x8000)
  270. #define GLOB_OFFS(x) (((x)*8)-(MAX_NB_GLOBALS*10)-(NB_TRAPS*8)+0x8000)
  271. #define TRAP_OFFS(x) (((x)-NB_TRAPS)*8+0x8000)
  272. #define STAT_OFFS(x) (((x)-MAX_NB_STATS)*4)
  273. #define SLOT(x)      ((x)*4)
  274.  
  275. #define RETURN(lab,fs,link)                        \
  276. %NEWLINE%    ALIGN8                            \
  277. %NEWLINE%    LONG    0                        \
  278. %NEWLINE%    WORD    (fs)*4                        \
  279. %NEWLINE%    WORD    ((fs)-(link))*4                    \
  280. %NEWLINE%    WORD    -0x8002-(.-LBL($entry))                \
  281. %NEWLINE%LBL(lab)
  282.  
  283. #define RETURN_LAZY(lab,fs,link)                    \
  284. %NEWLINE%    ALIGN8                            \
  285. %NEWLINE%    LONG    0                        \
  286. %NEWLINE%    WORD    -0x8000+(fs)*4                    \
  287. %NEWLINE%    WORD    ((fs)-(link))*4                    \
  288. %NEWLINE%    WORD    -0x8002-(.-LBL($entry))                \
  289. %NEWLINE%LBL(lab)
  290.  
  291. #define SUBPROC(lab)                            \
  292. %NEWLINE%    ALIGN8                            \
  293. %NEWLINE%    WORD    -0x8002-(.-LBL($entry))                \
  294. %NEWLINE%LBL(lab)
  295.  
  296. #define WRONG_NB_ARGS(x,n,lab)                        \
  297. %NEWLINE%    jsr DISP(TABLE_REG,TRAP_OFFS(x))            \
  298. %NEWLINE%    WORD n                            \
  299. %NEWLINE%    WORD .-LBL(lab)
  300.  
  301. #define TRAP(x,lab,fs,link)                        \
  302. %NEWLINE%    BRAS(    lab)                        \
  303. %NEWLINE%    nop                            \
  304. %NEWLINE%    ALIGN8                            \
  305. %NEWLINE%LBL(lab):                            \
  306. %NEWLINE%    jsr DISP(TABLE_REG,TRAP_OFFS(x))            \
  307. %NEWLINE%    WORD    fs*4                        \
  308. %NEWLINE%    WORD    (fs-link)*4                    \
  309. %NEWLINE%    WORD    -0x8002-(.-LBL($entry))
  310.  
  311. #define GET_TRAP_RETURN(nb_args)                    \
  312. %NEWLINE%    GET_TRAP_RET(nb_args)                    \
  313. %NEWLINE%    addql    IMM(SCM_type_PROCEDURE),DTEMP1
  314.  
  315. #define GET_TRAP_RET(nb_args)                        \
  316. %NEWLINE%    moveq    IMM(11+(nb_args*2)),DTEMP1            \
  317. %NEWLINE%    addl    PINC(SP),DTEMP1                    \
  318. %NEWLINE%    andw    IMM(-8),DTEMP1
  319.  
  320. #define MOVE_ARGS_TO_STACK(arg_count)                    \
  321. %NEWLINE%    movw    arg_count,DTEMP1                \
  322. %NEWLINE%    BPLS(    not_1_arg)                    \
  323. %NEWLINE%    moveq    IMM(1),DTEMP1        /* 1 arg passed */    \
  324. %NEWLINE%    movl    PVM1_REG,PDEC(SP)                \
  325. %NEWLINE%    BRAS(    args_pushed)                    \
  326. %NEWLINE%LBL(not_1_arg):                        \
  327. %NEWLINE%    BNES(    not_1_or_2_args)                \
  328. %NEWLINE%    moveq    IMM(2),DTEMP1        /* 2 args passed */    \
  329. %NEWLINE%    movl    PVM1_REG,PDEC(SP)                \
  330. %NEWLINE%    movl    PVM2_REG,PDEC(SP)                \
  331. %NEWLINE%    BRAS(    args_pushed)                    \
  332. %NEWLINE%LBL(not_1_or_2_args):                        \
  333. %NEWLINE%    subqw    IMM(1),DTEMP1                    \
  334. %NEWLINE%    BEQS(    args_pushed)                    \
  335. %NEWLINE%    movl    PVM1_REG,PDEC(SP)    /* 3 or more args passed */\
  336. %NEWLINE%    movl    PVM2_REG,PDEC(SP)                \
  337. %NEWLINE%    movl    PVM3_REG,PDEC(SP)                \
  338. %NEWLINE%LBL(args_pushed):
  339.  
  340. #define RESET_STACK                            \
  341. %NEWLINE%    movl    DISP(PSTATE_REG,SLOT(STACK_TOP)),SP        \
  342. %NEWLINE%    movl    DISP(PSTATE_REG,SLOT(Q_BOT)),LTQ_TAIL_REG    \
  343. %NEWLINE%    movl    SP,PINC(LTQ_TAIL_REG)                \
  344. %NEWLINE%    movl    LTQ_TAIL_REG,DISP(PSTATE_REG,SLOT(LTQ_HEAD))     \
  345. %NEWLINE%    movl    DISP(PSTATE_REG,SLOT(Q_TOP)),ATEMP1        \
  346. %NEWLINE%    movl    SP,PDEC(ATEMP1)                    \
  347. %NEWLINE%    movl    ATEMP1,DISP(PSTATE_REG,SLOT(DEQ_TAIL))        \
  348. %NEWLINE%    movl    ATEMP1,DISP(PSTATE_REG,SLOT(DEQ_HEAD))
  349.  
  350. #define MAKE_TEMP_TASK                            \
  351. %NEWLINE%    clrl    PDEC(HEAP_REG) /* Make legitimacy PH */        \
  352. %NEWLINE%    clrl    PDEC(HEAP_REG)                    \
  353. %NEWLINE%    movl    NULL_REG,PDEC(HEAP_REG)                \
  354. %NEWLINE%    lea    DISP(HEAP_REG,SCM_type_PLACEHOLDER-4),ATEMP2    \
  355. %NEWLINE%    movl    ATEMP2,PDEC(HEAP_REG)                \
  356. %NEWLINE%    clrl    PDEC(HEAP_REG) /* Make value PH */        \
  357. %NEWLINE%    clrl    PDEC(HEAP_REG)                    \
  358. %NEWLINE%    movl    NULL_REG,PDEC(HEAP_REG)                \
  359. %NEWLINE%    lea    DISP(HEAP_REG,SCM_type_PLACEHOLDER-4),ATEMP1    \
  360. %NEWLINE%    movl    ATEMP1,PDEC(HEAP_REG)                \
  361. %NEWLINE%    clrl    PDEC(HEAP_REG) /* Make task */            \
  362. %NEWLINE%    clrl    PDEC(HEAP_REG)                    \
  363. %NEWLINE%    movl    FALSE_REG,PDEC(HEAP_REG)            \
  364. %NEWLINE%    movl    ATEMP1,PDEC(HEAP_REG)                \
  365. %NEWLINE%    movl    ATEMP1,PDEC(HEAP_REG)                \
  366. %NEWLINE%    movl    ATEMP2,PDEC(HEAP_REG)                \
  367. %NEWLINE%    clrl    PDEC(HEAP_REG)                    \
  368. %NEWLINE%    clrl    PDEC(HEAP_REG)                    \
  369. %NEWLINE%    clrl    PDEC(HEAP_REG)                    \
  370. %NEWLINE%    movl    IMM(TASK_SIZE*0x400+(SCM_subtype_TASK*8)),PDEC(HEAP_REG) \
  371. %NEWLINE%    lea    DISP(HEAP_REG,SCM_type_SUBTYPED),ATEMP1        \
  372. %NEWLINE%    movl    ATEMP1,DISP(PSTATE_REG,SLOT(TEMP_TASK))
  373.  
  374. #ifdef STATS
  375.  
  376. #define STAT(n,x)                            \
  377. %NEWLINE%    addql IMM(n),DISP(PSTATE_REG,STAT_OFFS(x))
  378.  
  379. #define STAT_DTEMP1(x)                            \
  380. %NEWLINE%    addl  DTEMP1,DISP(PSTATE_REG,STAT_OFFS(x))
  381.  
  382. #else
  383.  
  384. #define STAT(n,x)
  385. #define STAT_DTEMP1(x)
  386.  
  387. #endif
  388.  
  389. #ifdef butterfly
  390.  
  391. #define ATOMCTA16 0 = a0, mask/incr = d1, adr = d0
  392. #define ATOMADD32 1
  393. #define ATOMAND32 2
  394. #define ATOMIOR32 3
  395.  
  396. #define DO_ATOMIC                            \
  397. %NEWLINE%    trap IMM(0xe)
  398.  
  399. #define DO_BTRANSFER                            \
  400. %NEWLINE%    trap IMM(0xc)
  401.  
  402. #define DO_GETRTC                            \
  403. %NEWLINE%    trap IMM(0xd)
  404.  
  405. #define ADD_TO_DTEMP1()                            \
  406. %NEWLINE%                    /* d0 = address, d1 = value */\
  407. %NEWLINE%    movw    IMM(ATOMADD32),PVM0_REG    /* a0 = atomadd32 command   */\
  408. %NEWLINE%    DO_ATOMIC            /* d0,a0,a1 not preserved   */
  409.  
  410. #define READ_AND_CLEAR_DTEMP1                        \
  411. %NEWLINE%                    /* d0 = address             */\
  412. %NEWLINE%    movw    IMM(ATOMAND32),PVM0_REG    /* a0 = atomand32 command   */\
  413. %NEWLINE%    moveq    IMM(0),PVM1_REG        /* d1 = mask                */\
  414. %NEWLINE%    DO_ATOMIC            /* d0,a0,a1 not preserved   */
  415.  
  416. #define READ_AND_SET_DTEMP1                        \
  417. %NEWLINE%                    /* d0 = address             */\
  418. %NEWLINE%    movw    IMM(ATOMIOR32),PVM0_REG    /* a0 = atomior32 command   */\
  419. %NEWLINE%    moveq    IMM(-1),PVM1_REG    /* d1 = mask                */\
  420. %NEWLINE%    DO_ATOMIC            /* d0,a0,a1 not preserved   */
  421.  
  422. #define LOCK_ATEMP1(lab)                        \
  423. %NEWLINE%     movl    ATEMP1,PVM4_REG                    \
  424. %NEWLINE%LBL(lab):                            \
  425. %NEWLINE%    movw    IMM(ATOMIOR32),PVM0_REG    /* a0 = atomior32 command   */\
  426. %NEWLINE%    movl    PVM4_REG,DTEMP1        /* d0 = address             */\
  427. %NEWLINE%    moveq    IMM(-1),PVM1_REG    /* d1 = mask                */\
  428. %NEWLINE%    DO_ATOMIC            /* d0,a0,a1 not preserved   */\
  429. %NEWLINE%    CMPL(    DTEMP1,PVM1_REG)                \
  430. %NEWLINE%    BEQS(    lab)                        \
  431. %NEWLINE%    movl    PVM4_REG,ATEMP1                    \
  432.  
  433. #define LOCK_ATEMP2(lab)                        \
  434. %NEWLINE%LBL(lab):                            \
  435. %NEWLINE%    movw    IMM(ATOMIOR32),PVM0_REG    /* a0 = atomior32 command   */\
  436. %NEWLINE%    movl    ATEMP2,DTEMP1        /* d0 = address             */\
  437. %NEWLINE%    moveq    IMM(-1),PVM1_REG    /* d1 = mask                */\
  438. %NEWLINE%    DO_ATOMIC            /* d0,a0,a1 not preserved   */\
  439. %NEWLINE%    CMPL(    DTEMP1,PVM1_REG)                \
  440. %NEWLINE%    BEQS(    lab)
  441.  
  442. #define BTRANSFER(lab)                            \
  443. %NEWLINE%    DO_BTRANSFER    /* a0 = src, d0 = dest, d1 = nb of bytes    */\
  444. %NEWLINE%            /* d0,d1,a1 not preserved                   */
  445.  
  446. #ifdef ELOG
  447.  
  448. #define LOG(event_num,lab)                        \
  449. %NEWLINE%    DO_GETRTC    /* d0 = real time clock value */    \
  450. %NEWLINE%    movl    DISP(PSTATE_REG,SLOT(ELOG_PTR)),ATEMP1        \
  451. %NEWLINE%    CMPL(    DISP(PSTATE_REG,SLOT(ELOG_BOT)),ATEMP1)        \
  452. %NEWLINE%    BEQS(    lab)                        \
  453. %NEWLINE%    movl    DTEMP1,PDEC(ATEMP1)                \
  454. %NEWLINE%    movb    IMM(event_num),IND(ATEMP1)            \
  455. %NEWLINE%    movl    ATEMP1,DISP(PSTATE_REG,SLOT(ELOG_PTR))        \
  456. %NEWLINE%LBL(lab):
  457.  
  458. #define PREV_LOG(n,lab)                            \
  459. %NEWLINE%    DO_GETRTC    /* d0 = real time clock value */    \
  460. %NEWLINE%    movl    DISP(PSTATE_REG,SLOT(ELOG_PTR)),ATEMP1        \
  461. %NEWLINE%    CMPL(    DISP(PSTATE_REG,SLOT(ELOG_BOT)),ATEMP1)        \
  462. %NEWLINE%    BEQS(    lab)                        \
  463. %NEWLINE%    movl    DTEMP1,PDEC(ATEMP1)                \
  464. %NEWLINE%    movb    DISP(ATEMP1,4*n),IND(ATEMP1)            \
  465. %NEWLINE%    movl    ATEMP1,DISP(PSTATE_REG,SLOT(ELOG_PTR))        \
  466. %NEWLINE%LBL(lab):
  467.  
  468. #else
  469.  
  470. #define LOG(x,lab)
  471. #define PREV_LOG(x,lab)
  472.  
  473. #endif
  474.  
  475. #else
  476.  
  477. #define ADD_TO_DTEMP1
  478.  
  479. #define READ_AND_CLEAR_DTEMP1                        \
  480. %NEWLINE%    movl    DTEMP1,ATEMP1                    \
  481. %NEWLINE%    movl    IND(ATEMP1),DTEMP1                \
  482. %NEWLINE%    clrl    IND(ATEMP1)
  483.  
  484. #define READ_AND_SET_DTEMP1                        \
  485. %NEWLINE%    movl    DTEMP1,ATEMP1                    \
  486. %NEWLINE%    movl    IND(ATEMP1),DTEMP1                \
  487. %NEWLINE%    movl    IMM(-1),IND(ATEMP1)
  488.  
  489. #define LOCK_ATEMP1(lab)                        \
  490. %NEWLINE%    movl    IND(ATEMP1),DTEMP1
  491.  
  492. #define LOCK_ATEMP2(lab)                        \
  493. %NEWLINE%    movl    IND(ATEMP2),DTEMP1
  494.  
  495. #define BTRANSFER(lab)                            \
  496. %NEWLINE%    movl    DTEMP1,ATEMP1                    \
  497. %NEWLINE%    lsrl    IMM(2),PVM1_REG                    \
  498. %NEWLINE%    subql    IMM(1),PVM1_REG                    \
  499. %NEWLINE%LBL(lab):                            \
  500. %NEWLINE%    movl    PINC(PVM0_REG),PINC(ATEMP1)            \
  501. %NEWLINE%    DBRA(    PVM1_REG,lab)
  502.  
  503. #define LOG(x,lab)
  504. #define PREV_LOG(x,lab)
  505.  
  506. #endif
  507.  
  508.  
  509. #define WORK_REQUEST THIEF
  510.  
  511.  
  512. /* Registers... */
  513.  
  514.  
  515. #define PVM0_REG        REG(a0)
  516. #define PVM1_REG        REG(d1)
  517. #define PVM2_REG        REG(d2)
  518. #define PVM3_REG        REG(d3)
  519. #define PVM4_REG        REG(d4)
  520. #define CLOSURE_REG     REG(d4)
  521. #define INTR_TIMER_REG  REG(d5)
  522. #define NULL_REG        REG(d6)
  523. #define PLACEHOLDER_REG REG(d6)
  524. #define FALSE_REG       REG(d7)
  525. #define PAIR_REG        REG(d7)
  526.  
  527. #define DTEMP1          REG(d0)
  528. #define ATEMP1          REG(a1)
  529. #define ATEMP2          REG(a2)
  530.  
  531. #define HEAP_REG        REG(a3)
  532. #define LTQ_TAIL_REG    REG(a4)
  533. #define PSTATE_REG      REG(a5)
  534. #define TABLE_REG       REG(a6)
  535. #define SP              REG(a7)
  536.  
  537.  
  538. /*---------------------------------------------------------------------------*/
  539.  
  540. /* Start of kernel... */
  541.  
  542. OBJECT_FILE_BEGIN
  543.     WORD    OFILE_VERSION_MAJOR    /* Stamp with appropriate version */
  544.     WORD    OFILE_VERSION_MINOR
  545.  
  546. /*---------------------------------------------------------------------------*/
  547.  
  548. /*
  549.  
  550. *** The first procedure (i.e. '###_kernel') is called from C as in:
  551. ***
  552. *** kernel_startup( table, pstate, os_M68881 );
  553.  
  554. */
  555.  
  556. #undef LBL
  557. #define LBL(x)MAKE_LBL(00,x)
  558.  
  559. BEGIN("###_kernel")
  560.  
  561.     movl    CONST(0),PVM0_REG    /* jump to #_kernel.startup */
  562.     jmp    IND(PVM0_REG)
  563.  
  564. /* Reserve space for saving C's context */
  565.  
  566.     LONG    0    /* C's D2 register */
  567.     LONG    0    /* C's D3 register */
  568.     LONG    0    /* C's D4 register */
  569.     LONG    0    /* C's D5 register */
  570.     LONG    0    /* C's D6 register */
  571.     LONG    0    /* C's D7 register */
  572.     LONG    0    /* C's A2 register */
  573.     LONG    0    /* C's A3 register */
  574.     LONG    0    /* C's A4 register */
  575.     LONG    0    /* C's A5 register */
  576.     LONG    0    /* C's A6 register */
  577.     LONG    0    /* C's SP register */
  578.  
  579.     SET(C_D2,6)
  580.     SET(C_D3,10)
  581.     SET(C_D4,14)
  582.     SET(C_D5,18)
  583.     SET(C_D6,22)
  584.     SET(C_D7,26)
  585.     SET(C_A2,30)
  586.     SET(C_A3,34)
  587.     SET(C_A4,38)
  588.     SET(C_A5,42)
  589.     SET(C_A6,46)
  590.     SET(C_SP,50)
  591.  
  592. CONSTS(1)
  593. PRIMITIVE("###_kernel.startup")
  594. END
  595.  
  596. /*---------------------------------------------------------------------------*/
  597.  
  598. #undef LBL
  599. #define LBL(x)MAKE_LBL(01,x)
  600.  
  601. BEGIN("###_kernel.trap_0")
  602.  
  603. /* global_jump */
  604.  
  605.     movl    IMM(SCM_false),FALSE_REG /* d7 was clobbered so restore it */
  606.  
  607.     movw    DTEMP1,PDEC(SP)        /* save argument count temporarily */
  608.     movl    ATEMP1,DTEMP1
  609.  
  610.     addl    IMM((MAX_NB_GLOBALS*2)+(NB_TRAPS*8-0x8000)),DTEMP1
  611.     subl    TABLE_REG,DTEMP1
  612.     asll    IMM(2),DTEMP1
  613.     addl    TABLE_REG,DTEMP1
  614.     subl    IMM((MAX_NB_GLOBALS*10)+(NB_TRAPS*8-0x8000)),DTEMP1
  615.  
  616.     movl    DTEMP1,ATEMP1
  617.     movl    PINC(ATEMP1),DTEMP1
  618.  
  619.     movl    DTEMP1,ATEMP2
  620.     addql    IMM(SCM_type_PAIR-SCM_type_PROCEDURE),DTEMP1
  621.     btst    DTEMP1,PAIR_REG
  622.     BNES(    not_a_proc)
  623.  
  624.     movl    ATEMP2,IND(ATEMP1)    /* replace trap adr by procedure adr */
  625.     movw    PINC(SP),DTEMP1        /* restore argument count and set flags */
  626.     jmp    IND(ATEMP2)        /* jump to procedure */
  627.  
  628. LBL(not_a_proc):
  629.     subql    IMM(4),ATEMP1        /* compute 'global variable index' */
  630.     addl    IMM((MAX_NB_GLOBALS*10)+(NB_TRAPS*8-0x8000)),ATEMP1
  631.     subl    TABLE_REG,ATEMP1
  632.  
  633.     MOVE_ARGS_TO_STACK(PINC(SP))
  634.  
  635. /* make room for 'global variable index' argument */
  636.  
  637.     movw    DTEMP1,PVM1_REG
  638.     movl    SP,ATEMP2
  639.     subql    IMM(4),SP
  640.     BRAS(    loop_entry)
  641. LBL(loop):
  642.     movl    PINC(ATEMP2),DISP(ATEMP2,-8)
  643. LBL(loop_entry):
  644.     DBRA(    PVM1_REG,loop)
  645.  
  646.     movl    ATEMP1,DISP(ATEMP2,-4)
  647.     addqw    IMM(1),DTEMP1
  648.  
  649.     movl    CONST(0),ATEMP1    /* apply ##exception.global-jump */
  650.     movl    CONST(1),ATEMP2
  651.     jmp    IND(ATEMP2)
  652.  
  653. CONSTS(2)
  654. PRIMITIVE("##exception.global-jump")
  655. PRIMITIVE("###_kernel.apply")
  656. END
  657.  
  658. /*---------------------------------------------------------------------------*/
  659.  
  660. #undef LBL
  661. #define LBL(x)MAKE_LBL(02,x)
  662.  
  663. BEGIN("###_kernel.trap_1")
  664.  
  665. /* touch d0 */
  666.  
  667.     movl    DTEMP1,ATEMP2
  668.  
  669.     GET_TRAP_RETURN(0)
  670.     movl    DTEMP1,PVM0_REG
  671.  
  672. LBL(touch):
  673.     movl    DISP(ATEMP2,SLOT(PH_VALUE)-SCM_type_PLACEHOLDER),DTEMP1
  674.     CMPL(    ATEMP2,DTEMP1)
  675.     BNES(    determined)
  676.  
  677.     LOG(EVENT_TOUCH_UNDET,log1)
  678.  
  679. #ifdef DETERMINE_IS_STRICT
  680.  
  681.     movl    CONST(0),ATEMP1
  682.     jmp    IND(ATEMP1)    /* jump to ###_kernel.touch */
  683. LBL(determined):
  684.  
  685. #else
  686.  
  687.     movl    PVM0_REG,PDEC(SP)
  688.     lea    PC_IND(ret),PVM0_REG
  689.     movl    CONST(0),ATEMP1
  690.     jmp    IND(ATEMP1)    /* jump to ###_kernel.touch */
  691. RETURN(ret,1,1):
  692.     movl    PINC(SP),PVM0_REG
  693. LBL(determined):
  694.     btst    DTEMP1,PLACEHOLDER_REG
  695.     BNES(    touched)
  696.     movl    DTEMP1,ATEMP2
  697.     BRAS(    touch)
  698. LBL(touched):
  699.  
  700. #endif
  701.  
  702.     jmp    IND(PVM0_REG)
  703.  
  704. CONSTS(1)
  705. PRIMITIVE("###_kernel.touch")
  706. END
  707.  
  708. /*---------------------------------------------------------------------------*/
  709.  
  710. #undef LBL
  711. #define LBL(x)MAKE_LBL(03,x)
  712.  
  713. BEGIN("###_kernel.trap_2")
  714.  
  715. /* touch d1 */
  716.  
  717.     GET_TRAP_RETURN(0)
  718.     movl    DTEMP1,PVM0_REG
  719.  
  720. LBL(touch):
  721.     movl    PVM1_REG,ATEMP2
  722.     movl    DISP(ATEMP2,SLOT(PH_VALUE)-SCM_type_PLACEHOLDER),PVM1_REG
  723.     CMPL(    ATEMP2,PVM1_REG)
  724.     BNES(    determined)
  725.  
  726.     LOG(EVENT_TOUCH_UNDET,log1)
  727.  
  728. #ifdef DETERMINE_IS_STRICT
  729.  
  730.     movl    CONST(0),ATEMP1
  731.     jmp    IND(ATEMP1)    /* jump to ###_kernel.touch */
  732. LBL(determined):
  733.  
  734. #else
  735.  
  736.     movl    PVM0_REG,PDEC(SP)
  737.     lea    PC_IND(ret),PVM0_REG
  738.     movl    CONST(0),ATEMP1
  739.     jmp    IND(ATEMP1)    /* jump to ###_kernel.touch */
  740. RETURN(ret,1,1):
  741.     movl    PINC(SP),PVM0_REG
  742. LBL(determined):
  743.     btst    PVM1_REG,PLACEHOLDER_REG
  744.     BEQS(    touch)
  745.  
  746. #endif
  747.  
  748.     jmp    IND(PVM0_REG)
  749.  
  750. CONSTS(1)
  751. PRIMITIVE("###_kernel.touch")
  752. END
  753.  
  754. /*---------------------------------------------------------------------------*/
  755.  
  756. #undef LBL
  757. #define LBL(x)MAKE_LBL(04,x)
  758.  
  759. BEGIN("###_kernel.trap_3")
  760.  
  761. /* touch d2 */
  762.  
  763.     GET_TRAP_RETURN(0)
  764.     movl    DTEMP1,PVM0_REG
  765.  
  766. LBL(touch):
  767.     movl    PVM2_REG,ATEMP2
  768.     movl    DISP(ATEMP2,SLOT(PH_VALUE)-SCM_type_PLACEHOLDER),PVM2_REG
  769.     CMPL(    ATEMP2,PVM2_REG)
  770.     BNES(    determined)
  771.  
  772.     LOG(EVENT_TOUCH_UNDET,log1)
  773.  
  774. #ifdef DETERMINE_IS_STRICT
  775.  
  776.     movl    CONST(0),ATEMP1
  777.     jmp    IND(ATEMP1)    /* jump to ###_kernel.touch */
  778. LBL(determined):
  779.  
  780. #else
  781.  
  782.     movl    PVM0_REG,PDEC(SP)
  783.     lea    PC_IND(ret),PVM0_REG
  784.     movl    CONST(0),ATEMP1
  785.     jmp    IND(ATEMP1)    /* jump to ###SP),DTEMP1
  786.  
  787.     CMPL(    DTEMP1,HEAP_REG)
  788.     subl    DTEMP1,HEAP_REG    /* allocate space and check heap overflow */
  789.     BCSS(    overflow_on_alloc)
  790.     CMPL(    DISP(PSTATE_REG,SLOT(HEAP_LIM)),HEAP_REG)
  791.     BCCS(    allocated)
  792. LBL(overflow_on_alloc):
  793.     addl    DTEMP1,HEAP_REG    /* restore correct heap ptr */
  794.  
  795. /* Then use a smaller heap margin and signal a heap overflow */
  796.  
  797.     movl    DISP(PSTATE_REG,SLOT(HEAP_MARGIN)),DTEMP1
  798.     BEQS(    fatal_overflow)
  799.  
  800.     subl    DTEMP1,DISP(PSTATE_REG,SLOT(HEAP_LIM))
  801.     moveq    IMM(0),DTEMP1
  802.     movl    DTEMP1,DISP(PSTATE_REG,SLOT(HEAP_MARGIN))
  803.  
  804. /* continuation must be discarded... */
  805.  
  806.     movl    DISP(PSTATE_REG,SLOT(BOS_RET)),PVM0_REG
  807.  
  808.     movl    CONST(1),ATEMP1    /* jump to ##exception.heap-overflow proc */
  809.     moveq    IMM(1),DTEMP1    /* passing 0 argument */
  810.     jmp    IND(ATEMP1)
  811.  
  812. LBL(fatal_overflow):
  813.  
  814.     movl    DISP(PSTATE_REG,SLOT(BOS_RET)),PVM0_REG
  815.  
  816.     movl    CONST(2),ATEMP1
  817.     moveq    IMM(1),DTEMP1
  818.     jmp    IND(ATEMP1)
  819.  
  820. LBL(allocated):
  821.  
  822. /* Check to see if we can grow the heap margin */
  823.  
  824.     movl    DISP(PSTATE_REG,SLOT(HEAP_LIM)),DTEMP1
  825.     subl    DISP(PSTATE_REG,SLOT(HEAP_MARGIN)),DTEMP1
  826.     addl    DISP(PSTATE_REG,SLOT(HEAP_MAX_MARGIN)),DTEMP1
  827.     CMPL(    DTEMP1,HEAP_REG)
  828.     BCSS(    cant_grow)
  829.  
  830.     movl    DTEMP1,DISP(PSTATE_REG,SLOT(HEAP_LIM))
  831.     movl    DISP(PSTATE_REG,SLOT(HEAP_MAX_MARGIN)),DISP(PSTATE_REG,SLOT(HEAP_MARGIN))
  832.  
  833. LBL(cant_grow):
  834.     movl    PINC(SP),PVM4_REG
  835.     movl    PINC(SP),PVM3_REG
  836.     movl    PINC(SP),PVM2_REG
  837.     movl    PINC(SP),PVM1_REG
  838.     movl    PINC(SP),PVM0_REG
  839.     rts
  840.  
  841. CONSTS(3)
  842. PRIMITIVE("##gc")
  843. PRIMITIVE("##exception.heap-overflow")
  844. PRIMITIVE("##fatal-heap-overflow")
  845. END
  846.  
  847. /*---------------------------------------------------------------------------*/
  848.  
  849. #undef LBL
  850. #define LBL(x)MAKE_LBL(16,x)
  851.  
  852. BEGIN("###_kernel.trap_15")
  853.  
  854. /* closure_alloc */
  855.  
  856.     movl    DTEMP1,ATEMP2
  857.  
  858.     GET_TRAP_RETURN(0)
  859.     movl    DTEMP1,PDEC(SP)
  860.  
  861.     movl    ATEMP2,DTEMP1
  862.     movl    DTEMP1,PDEC(SP)
  863.  
  864.     addl    IMM(CLOSURE_BLOCK_LENGTH+CACHE_LINE_LENGTH),DTEMP1
  865.     subl    DTEMP1,HEAP_REG
  866.     CMPL(    DISP(PSTATE_REG,SLOT(HEAP_LIM)),HEAP_REG) /* heap overflow */
  867.     BCCS(    ok)
  868.  
  869.     TRAP(heap_alloc2_trap,alloc,2,1)
  870.  
  871. LBL(ok):
  872.     movl    HEAP_REG,DTEMP1
  873.     addl    IMM(CACHE_LINE_LENGTH),DTEMP1
  874.     andw    IMM(-CACHE_LINE_LENGTH),DTEMP1
  875.     movl    DTEMP1,ATEMP1
  876.     movl    ATEMP1,DISP(PSTATE_REG,SLOT(CLOSURE_LIM))
  877.     addl    IMM(CLOSURE_BLOCK_LENGTH),ATEMP1
  878.     movl    ATEMP1,DISP(PSTATE_REG,SLOT(CLOSURE_PTR))
  879.  
  880.     addl    PINC(SP),ATEMP1
  881.  
  882. /* init closure block: */
  883.  
  884.     movl    IMM(0x80080000+JSR_OP),DTEMP1
  885.     lea    PC_IND(closure_trampoline),ATEMP2
  886.     BRAS(    loop_entry)
  887. LBL(loop):
  888.     subql    IMM(CACHE_LINE_LENGTH-8),ATEMP1
  889.     movl    ATEMP2,PDEC(ATEMP1)
  890.     movl    DTEMP1,PDEC(ATEMP1)
  891. LBL(loop_entry):
  892.     CMPL(    ATEMP1,HEAP_REG)
  893.     BLTS(    loop)
  894.  
  895.     movl    DISP(PSTATE_REG,SLOT(FLUSH_WRITES)),PDEC(SP)
  896.     jsr    DISP(TABLE_REG,TRAP_OFFS(C_TRAP_trap))
  897.  
  898.     movl    DISP(PSTATE_REG,SLOT(CLOSURE_PTR)),ATEMP2
  899.  
  900.     rts
  901.  
  902. LBL(closure_trampoline):
  903.     movl    IND(SP),ATEMP1
  904.     movl    PDEC(ATEMP1),ATEMP1
  905.     jmp    IND(ATEMP1)
  906.  
  907. CONSTS(0)
  908. END
  909.  
  910. /*---------------------------------------------------------------------------*/
  911.  
  912. #undef LBL
  913. #define LBL(x)MAKE_LBL(17,x)
  914.  
  915. BEGIN("###_kernel.trap_16")
  916.  
  917. /* delay_future */
  918.  
  919.     GET_TRAP_RETURN(0)
  920.     movl    DTEMP1,PVM0_REG
  921.  
  922. /* Allocate special "DELAY" frame. */
  923.  
  924.     moveq    IMM(11+4+PH_SIZE*4),DTEMP1
  925.     addw    DISP(PVM0_REG,-6),DTEMP1    /* get fs */
  926.     andw    IMM(-8),DTEMP1
  927.     subl    DTEMP1,HEAP_REG
  928.  
  929. /* Check need to GC. */
  930.  
  931.     CMPL(    DISP(PSTATE_REG,SLOT(HEAP_LIM)),HEAP_REG)
  932.     BCCS(    space_allocated)
  933. LBL(gc_needed):
  934.     movl    PVM0_REG,PDEC(SP)
  935.     TRAP(heap_alloc2_trap,alloc,1,1)
  936.     movl    PINC(SP),PVM0_REG
  937.  
  938. LBL(space_allocated):
  939.     addw    IMM(PH_SIZE*4),HEAP_REG
  940.  
  941.     moveq    IMM(4),DTEMP1
  942.     addw    DISP(PVM0_REG,-6),DTEMP1
  943.     asll    IMM(8),DTEMP1
  944.     movb    IMM(SCM_subtype_VECTOR*8),DTEMP1
  945.     movl    DTEMP1,IND(HEAP_REG)
  946.  
  947. /* Copy the frame. */
  948.  
  949.     lsrl    IMM(8),DTEMP1
  950.     lsrl    IMM(2),DTEMP1
  951.     subql    IMM(2),DTEMP1
  952.  
  953.     moveq    IMM(0),PVM1_REG
  954.     movw    DISP(PVM0_REG,-4),PVM1_REG    /* get link */
  955.     movl    INXW(SP,PVM1_REG,0),ATEMP2
  956.  
  957.     lea    DISP(HEAP_REG,SLOT(1)),ATEMP1
  958.     movl    PVM0_REG,PINC(ATEMP1)
  959. LBL(copy_loop):
  960.     movl    PINC(SP),PINC(ATEMP1)
  961.     DBRA(    DTEMP1,copy_loop)
  962.  
  963. /* Make placeholder. */
  964.  
  965.     lea    DISP(HEAP_REG,SCM_type_SUBTYPED),ATEMP1
  966.     clrl    PDEC(HEAP_REG)
  967.     movl    ATEMP1,PDEC(HEAP_REG)
  968.     movl    NULL_REG,PDEC(HEAP_REG)
  969.     lea    DISP(HEAP_REG,SCM_type_PLACEHOLDER-4),ATEMP1
  970.     movl    ATEMP1,PDEC(HEAP_REG)
  971.  
  972. /* Return placeholder. */
  973.  
  974.     movl    ATEMP1,PVM1_REG
  975.  
  976.     jmp    IND(ATEMP2)
  977.  
  978. CONSTS(0)
  979. END
  980.  
  981. /*---------------------------------------------------------------------------*/
  982.  
  983. #undef LBL
  984. #define LBL(x)MAKE_LBL(18,x)
  985.  
  986. BEGIN("###_kernel.trap_17")
  987.  
  988. /* eager_future */
  989.  
  990.     GET_TRAP_RETURN(0)
  991.     movl    DTEMP1,PVM0_REG
  992.  
  993. /* broken... */
  994.  
  995.     jmp    IND(PVM0_REG)
  996.  
  997. CONSTS(0)
  998. END
  999.  
  1000. /*---------------------------------------------------------------------------*/
  1001.  
  1002. #undef LBL
  1003. #define LBL(x)MAKE_LBL(19,x)
  1004.  
  1005. BEGIN("###_kernel.trap_18")
  1006.  
  1007. /* steal_conflict */
  1008.  
  1009.     GET_TRAP_RETURN(0)
  1010.     movl    DTEMP1,ATEMP2
  1011.  
  1012. /* get consistent value for LTQ_HEAD */
  1013.  
  1014.     movl    FALSE_REG,DISP(PSTATE_REG,SLOT(STEAL_LOCKO))
  1015.  
  1016. /*
  1017.     tstl    DISP(PSTATE_REG,SLOT(STEAL_LOCKV))
  1018.     BEQS(    locked)
  1019.  
  1020.     addql    IMM(8),DISP(PSTATE_REG,SLOT(56))
  1021. */
  1022.  
  1023. LBL(lock_steal):
  1024.     tstl    DISP(PSTATE_REG,SLOT(STEAL_LOCKV))
  1025.     BNES(    lock_steal)
  1026. LBL(locked):
  1027.  
  1028.     movl    DISP(PSTATE_REG,SLOT(LTQ_HEAD)),ATEMP1
  1029.  
  1030.     clrl    DISP(PSTATE_REG,SLOT(STEAL_LOCKO))
  1031.  
  1032. /* Who won the race for the continuation? */
  1033.  
  1034.     CMPL(    ATEMP1,LTQ_TAIL_REG)
  1035.     BCSS(    thief_won)
  1036.  
  1037. /* Continue normally */
  1038.  
  1039.     jmp    IND(ATEMP2)
  1040.  
  1041. LBL(thief_won):
  1042.  
  1043.     movl    SP,PINC(LTQ_TAIL_REG)
  1044.  
  1045.     movl    CONST(0),ATEMP1
  1046.     addw    IMM(16),ATEMP1
  1047.     movl    ATEMP1,DISP(PSTATE_REG,SLOT(PARENT_RET))
  1048.  
  1049. #ifdef debug
  1050. /*****/    pea    PC_IND($entry)
  1051. /*****/    movl    PINC(SP),DISP(PSTATE_REG,SLOT(56))
  1052. /*****/    movl    IMM(0),DISP(PSTATE_REG,SLOT(57))
  1053. /*****/    movl    IMM(0),DISP(PSTATE_REG,SLOT(58))
  1054. #endif
  1055.  
  1056.     movl    DISP(PSTATE_REG,SLOT(BOS_RET)),ATEMP1
  1057.     jmp    IND(ATEMP1)
  1058.  
  1059. CONSTS(1)
  1060. PRIMITIVE("###_kernel.task")
  1061. END
  1062.  
  1063. /*---------------------------------------------------------------------------*/
  1064.  
  1065. #undef LBL
  1066. #define LBL(x)MAKE_LBL(20,x)
  1067.  
  1068. BEGIN("###_kernel.trap_19")
  1069.  
  1070.     BRAS(    $entry)
  1071.  
  1072. CONSTS(0)
  1073. END
  1074.  
  1075. /*---------------------------------------------------------------------------*/
  1076.  
  1077. #undef LBL
  1078. #define LBL(x)MAKE_LBL(21,x)
  1079.  
  1080. BEGIN("###_kernel.trap_20")
  1081.  
  1082.     BRAS(    $entry)
  1083.  
  1084. CONSTS(0)
  1085. END
  1086.  
  1087. /*---------------------------------------------------------------------------*/
  1088.  
  1089. #undef LBL
  1090. #define LBL(x)MAKE_LBL(22,x)
  1091.  
  1092. BEGIN("###_kernel.trap_21")
  1093.  
  1094.     BRAS(    $entry)
  1095.  
  1096. CONSTS(0)
  1097. END
  1098.  
  1099. /*---------------------------------------------------------------------------*/
  1100.  
  1101. #undef LBL
  1102. #define LBL(x)MAKE_LBL(23,x)
  1103.  
  1104. BEGIN("###_kernel.trap_22")
  1105.  
  1106. /* C_TRAP */
  1107.  
  1108.     movl    REG(a4),PDEC(SP)
  1109.     movl    REG(a3),PDEC(SP)
  1110.     movl    REG(a2),PDEC(SP)
  1111.     movl    REG(a1),PDEC(SP)
  1112.     movl    REG(a0),PDEC(SP)
  1113.     movl    DISP(SP,4+SLOT(5)),REG(a0)
  1114.     movl    REG(d7),PDEC(SP)
  1115.     movl    REG(d6),PDEC(SP)
  1116.     movl    REG(d5),PDEC(SP)
  1117.     movl    REG(d4),PDEC(SP)
  1118.     movl    REG(d3),PDEC(SP)
  1119.     movl    REG(d2),PDEC(SP)
  1120.     movl    REG(d1),PDEC(SP)
  1121.     movl    REG(d0),PDEC(SP)
  1122.  
  1123.     movl    SP,DISP(PSTATE_REG,SLOT(STACK_PTR))
  1124.  
  1125.     movl    CONST(0),REG(a1)        /* restore C's registers */
  1126. #ifndef MIN_C_CONTEXT
  1127.     movl    DISP(REG(a1),C_D2),REG(d2)
  1128.     movl    DISP(REG(a1),C_D3),REG(d3)
  1129.     movl    DISP(REG(a1),C_D4),REG(d4)
  1130.     movl    DISP(REG(a1),C_D5),REG(d5)
  1131.     movl    DISP(REG(a1),C_D6),REG(d6)
  1132.     movl    DISP(REG(a1),C_D7),REG(d7)
  1133.     movl    DISP(REG(a1),C_A2),REG(a2)
  1134.     movl    DISP(REG(a1),C_A3),REG(a3)
  1135.     movl    DISP(REG(a1),C_A4),REG(a4)
  1136. #endif
  1137.     movl    DISP(REG(a1),C_A5),REG(a5)
  1138.     movl    DISP(REG(a1),C_A6),REG(a6)
  1139.     movl    DISP(REG(a1),C_SP),SP
  1140.  
  1141.     jsr    IND(REG(a0))            /* call C procedure */
  1142.  
  1143.     movl    CONST(0),REG(a2)
  1144.     movl    DISP(REG(a2),C_SP),ATEMP1    /* get TABLE_REG & PSTATE_REG */
  1145.     movl    DISP(ATEMP1,4),TABLE_REG    /* restore Scheme context */
  1146.     movl    DISP(ATEMP1,8),PSTATE_REG
  1147.  
  1148.     movl    DISP(PSTATE_REG,SLOT(STACK_PTR)),SP
  1149.  
  1150.     movl    PINC(SP),REG(d0)
  1151.     movl    PINC(SP),REG(d1)
  1152.     movl    PINC(SP),REG(d2)
  1153.     movl    PINC(SP),REG(d3)
  1154.     movl    PINC(SP),REG(d4)
  1155.     movl    PINC(SP),REG(d5)
  1156.     movl    PINC(SP),REG(d6)
  1157.     movl    PINC(SP),REG(d7)
  1158.     movl    PINC(SP),REG(a0)
  1159.     movl    PINC(SP),REG(a1)
  1160.     movl    PINC(SP),REG(a2)
  1161.     movl    PINC(SP),REG(a3)
  1162.     movl    PINC(SP),REG(a4)
  1163.  
  1164.     movl    PINC(SP),IND(SP)
  1165.  
  1166.     rts
  1167.  
  1168. CONSTS(1)
  1169. PRIMITIVE("###_kernel")
  1170. END
  1171.  
  1172. /*---------------------------------------------------------------------------*/
  1173.  
  1174. #undef LBL
  1175. #define LBL(x)MAKE_LBL(24,x)
  1176.  
  1177. BEGIN("###_kernel.trap_23")
  1178.  
  1179. /* C_CALL */
  1180.  
  1181.     movl    CONST(0),REG(a2)
  1182.     movl    DISP(REG(a2),C_SP),ATEMP2
  1183.  
  1184.     movl    IMM(SCM_marker),PDEC(ATEMP2)
  1185.  
  1186.     tstw    DTEMP1
  1187.     BMIS(    passed_1arg)
  1188.     BEQS(    passed_2args)
  1189.  
  1190.     subqw    IMM(3),DTEMP1
  1191.     BMIS(    move_remaining_args)
  1192.  
  1193.     movl    PVM3_REG,TEMP1)        /* jump to procedure (with >= 3 args) */
  1194.  
  1195. LBL(pass_0arg):
  1196.     moveq    IMM(1),DTEMP1
  1197.     jmp    IND(ATEMP1)        /* jump to procedure (with no arg) */
  1198.  
  1199. LBL(pass_1arg):
  1200.     movl    PINC(SP),PVM1_REG
  1201.     moveq    IMM(-1),DTEMP1
  1202.     jmp    IND(ATEMP1)        /* jump to procedure (with 1 arg) */
  1203.  
  1204. LBL(pass_2args):
  1205.     movl    PINC(SP),PVM2_REG
  1206.     movl    PINC(SP),PVM1_REG
  1207.     moveq    IMM(0),DTEMP1
  1208.     jmp    IND(ATEMP1)        /* jump to procedure (with 2 args) */
  1209.  
  1210. CONSTS(0)
  1211. END
  1212.  
  1213. /*---------------------------------------------------------------------------*/
  1214.  
  1215. #undef LBL
  1216. #define LBL(x)MAKE_LBL(27,x)
  1217.  
  1218. BEGIN("###_kernel.wrong-nb-arg")
  1219.  
  1220. /* make room for 'procedure' argument */
  1221.  
  1222.     movw    DTEMP1,PVM1_REG
  1223.     movl    SP,ATEMP2
  1224.     subql    IMM(4),SP
  1225.     BRAS(    loop_entry)
  1226. LBL(loop):
  1227.     movl    PINC(ATEMP2),DISP(ATEMP2,-8)
  1228. LBL(loop_entry):
  1229.     DBRA(    PVM1_REG,loop)
  1230.  
  1231.     movl    ATEMP1,DISP(ATEMP2,-4)    /* put 'procedure' argument */
  1232.     addqw    IMM(1),DTEMP1
  1233.  
  1234.     movl    CONST(0),ATEMP1    /* apply ##exception.wrong-nb-arg */
  1235.     movl    CONST(1),ATEMP2
  1236.     jmp    IND(ATEMP2)
  1237.  
  1238. CONSTS(2)
  1239. PRIMITIVE("##exception.wrong-nb-arg")
  1240. PRIMITIVE("###_kernel.apply")
  1241. END
  1242.  
  1243. /*---------------------------------------------------------------------------*/
  1244.  
  1245. #undef LBL
  1246. #define LBL(x)MAKE_LBL(28,x)
  1247.  
  1248. BEGIN("###_kernel.switch-task")
  1249.  
  1250.     CMPL(    DISP(PSTATE_REG,SLOT(LTQ_HEAD)),LTQ_TAIL_REG)
  1251.     BNES(    there_are_other_tasks)
  1252.  
  1253.     CMPL(    DISP(PSTATE_REG,SLOT(WORKQ_TAIL)),NULL_REG)
  1254.     BNES(    there_are_other_tasks)
  1255.  
  1256.     movl    FALSE_REG,PVM1_REG    /* no other tasks to switch to */
  1257.     jmp    IND(PVM0_REG)
  1258.  
  1259. LBL(there_are_other_tasks):
  1260.  
  1261.     LOG(EVENT_TASK_SWITCH,log1)
  1262.  
  1263.     movl    PVM0_REG,PDEC(SP)
  1264.  
  1265. /* Call ###_kernel.transfer-lazy-tasks-to-heap. */
  1266.  
  1267.     pea    PC_IND(ret1)
  1268.     movl    CONST(0),ATEMP1
  1269.     jmp    IND(ATEMP1)
  1270. RETURN(ret1,1,1):
  1271.  
  1272. /* Call ###_kernel.transfer-stack-to-heap. */
  1273.  
  1274. /* ###_kernel.transfer-lazy-tasks-to-heap has reserved enough */
  1275. /* space, so no GC check required.                            */
  1276.  
  1277.     pea    PC_IND(ret2)
  1278.     movl    CONST(1),ATEMP1
  1279.     jmp    IND(ATEMP1)
  1280. LBL(ret2):
  1281.  
  1282. /* Save state of current task. */
  1283.  
  1284.     movl    DISP(PSTATE_REG,SLOT(CURRENT_TASK)),ATEMP1
  1285.  
  1286.     movl    PINC(SP),PVM0_REG
  1287.     movl    PVM0_REG,DISP(ATEMP1,SLOT(TASK_CONT_RET)+4-SCM_type_SUBTYPED)
  1288.     movl    PVM2_REG,DISP(ATEMP1,SLOT(TASK_CONT_FRAME)+4-SCM_type_SUBTYPED)
  1289.     movl    DISP(PSTATE_REG,SLOT(CURRENT_DYN_ENV)),DISP(ATEMP1,SLOT(TASK_CONT_DYN_ENV)+4-SCM_type_SUBTYPED)
  1290.     movl    IMM(SCM_true),DISP(ATEMP1,SLOT(TASK_VALUE)+4-SCM_type_SUBTYPED)
  1291.  
  1292. /* Add task to workq. */
  1293.  
  1294.     movl    ATEMP1,PDEC(HEAP_REG)
  1295.  
  1296. #ifdef MAINTAIN_TASK_STATUS
  1297.  
  1298. /* Change task's status to READY */
  1299.  
  1300.     movl    HEAP_REG,DISP(ATEMP1,SLOT(TASK_STATUS)+4-SCM_type_SUBTYPED)
  1301.  
  1302. #endif
  1303.  
  1304.     movl    FALSE_REG,DISP(PSTATE_REG,SLOT(WORKQ_LOCKO))
  1305. LBL(lock_workq):
  1306.     tstl    DISP(PSTATE_REG,SLOT(WORKQ_LOCKV))
  1307.     BNES(    lock_workq)
  1308.  
  1309.     movl    DISP(PSTATE_REG,SLOT(WORKQ_TAIL)),ATEMP1
  1310.     CMPL(    ATEMP1,NULL_REG)
  1311.     BNES(    non_empty_queue)
  1312.     movl    HEAP_REG,DISP(PSTATE_REG,SLOT(WORKQ_HEAD))
  1313.     BRAS(    fix_tail)
  1314. LBL(non_empty_queue):
  1315.     movl    HEAP_REG,PDEC(ATEMP1)
  1316.  
  1317. LBL(fix_tail):
  1318.     movl    HEAP_REG,DISP(PSTATE_REG,SLOT(WORKQ_TAIL))
  1319.  
  1320.     movl    NULL_REG,PDEC(HEAP_REG)
  1321.  
  1322.     clrl    DISP(PSTATE_REG,SLOT(WORKQ_LOCKO))
  1323.  
  1324. /* Go idle. */
  1325.  
  1326.     moveq    IMM(0),PVM1_REG
  1327.     movl    CONST(2),ATEMP1
  1328.     jmp    IND(ATEMP1)
  1329.  
  1330. CONSTS(3)
  1331. PRIMITIVE("###_kernel.transfer-lazy-tasks-to-heap")
  1332. PRIMITIVE("###_kernel.transfer-stack-to-heap")
  1333. PRIMITIVE("###_kernel.idle")
  1334. END
  1335.  
  1336. /*---------------------------------------------------------------------------*/
  1337.  
  1338. #undef LBL
  1339. #define LBL(x)MAKE_LBL(29,x)
  1340.  
  1341. BEGIN("###_kernel.idle")
  1342.  
  1343. #ifdef MAINTAIN_TASK_STATUS
  1344.  
  1345.     BEQS(    find_work)
  1346.  
  1347.     movl    PVM1_REG,ATEMP1
  1348.  
  1349. /* Check if task is really READY */
  1350.  
  1351.     lea    DISP(ATEMP1,SLOT(TASK_LOCKV)+4-SCM_type_SUBTYPED),ATEMP1
  1352. LBL(lock_task1):
  1353.     LOCK_ATEMP1(lock1)
  1354.     tstl    DISP(ATEMP1,SLOT(TASK_LOCKO-TASK_LOCKV))
  1355.     BEQS(    task_locked1)
  1356.     clrl    IND(ATEMP1)
  1357.     BRAS(    lock_task1)
  1358.  
  1359. LBL(task_locked1):
  1360.     movl    DISP(ATEMP1,SLOT(TASK_STATUS-TASK_LOCKV)),DTEMP1
  1361.     btst    DTEMP1,PAIR_REG
  1362.     BNES(    task_not_ready1)
  1363.  
  1364.     movl    DTEMP1,ATEMP2        /* remove task from workq */
  1365.     movl    FALSE_REG,IND(ATEMP2)
  1366.  
  1367. /* Change task's status to RUNNING */
  1368.  
  1369.     movl    PSTATE_REG,DISP(ATEMP1,SLOT(TASK_STATUS-TASK_LOCKV))
  1370.     clrl    IND(ATEMP1)
  1371.  
  1372.     lea    DISP(ATEMP1,-(SLOT(TASK_LOCKV)+4-SCM_type_SUBTYPED)),ATEMP1
  1373.  
  1374. #ifdef debug
  1375. /*****/    movl    IMM(1),DISP(PSTATE_REG,SLOT(58))
  1376. #endif
  1377.  
  1378.     BRAW(    resume_task)
  1379.  
  1380. LBL(task_not_ready1):
  1381.     clrl    IND(ATEMP1)
  1382.  
  1383. #endif
  1384.  
  1385. LBL(find_work):
  1386.  
  1387.     LOG(EVENT_IDLE,log1)
  1388.  
  1389. LBL(try_our_workq):
  1390.  
  1391. /* Try removing task from our own workq. */
  1392.  
  1393.     movl    FALSE_REG,DISP(PSTATE_REG,SLOT(WORKQ_LOCKO))
  1394. LBL(lock_workq1):
  1395.     tstl    DISP(PSTATE_REG,SLOT(WORKQ_LOCKV))
  1396.     BNES(    lock_workq1)
  1397.  
  1398.     movl    DISP(PSTATE_REG,SLOT(WORKQ_HEAD)),ATEMP1
  1399.     CMPL(    ATEMP1,NULL_REG)
  1400.     BEQS(    empty_queue1)
  1401.     movl    PDEC(ATEMP1),ATEMP2
  1402.     movl    ATEMP2,DISP(PSTATE_REG,SLOT(WORKQ_HEAD))
  1403.     CMPL(    ATEMP2,NULL_REG)
  1404.     BNES(    done1)
  1405.     movl    ATEMP2,DISP(PSTATE_REG,SLOT(WORKQ_TAIL))
  1406. LBL(done1):
  1407.  
  1408.     clrl    DISP(PSTATE_REG,SLOT(WORKQ_LOCKO))
  1409.  
  1410. /* Check if task is really READY */
  1411.  
  1412.     movl    DISP(ATEMP1,SLOT(1)),ATEMP1
  1413.  
  1414. #ifdef MAINTAIN_TASK_STATUS
  1415.  
  1416.     CMPL(    ATEMP1,FALSE_REG)
  1417.     BEQS(    try_our_workq)
  1418.  
  1419.     lea    DISP(ATEMP1,SLOT(TASK_LOCKV)+4-SCM_type_SUBTYPED),ATEMP1
  1420. LBL(lock_task2):
  1421.     LOCK_ATEMP1(lock2)
  1422.     tstl    DISP(ATEMP1,SLOT(TASK_LOCKO-TASK_LOCKV))
  1423.     BEQS(    task_locked2)
  1424.     clrl    IND(ATEMP1)
  1425.     BRAS(    lock_task2)
  1426.  
  1427. LBL(task_not_ready2):
  1428.     clrl    IND(ATEMP1)
  1429.     BRAS(    try_our_workq)
  1430.  
  1431. LBL(task_locked2):
  1432.     movl    DISP(ATEMP1,SLOT(TASK_STATUS-TASK_LOCKV)),DTEMP1
  1433.     btst    DTEMP1,PAIR_REG
  1434.     BNES(    task_not_ready2)
  1435.  
  1436.     movl    DTEMP1,ATEMP2        /* remove task from workq */
  1437.     movl    FALSE_REG,IND(ATEMP2)
  1438.  
  1439. /* Change task's status to RUNNING */
  1440.  
  1441.     movl    PSTATE_REG,DISP(ATEMP1,SLOT(TASK_STATUS-TASK_LOCKV))
  1442.     clrl    IND(ATEMP1)
  1443.  
  1444.     lea    DISP(ATEMP1,-(SLOT(TASK_LOCKV)+4-SCM_type_SUBTYPED)),ATEMP1
  1445.  
  1446. #endif
  1447.  
  1448. #ifdef debug
  1449. /*****/    movl    IMM(2),DISP(PSTATE_REG,SLOT(58))
  1450. #endif
  1451.  
  1452.     BRAW(    resume_task)
  1453.  
  1454. LBL(empty_queue1):
  1455.     clrl    DISP(PSTATE_REG,SLOT(WORKQ_LOCKO))
  1456.  
  1457. LBL(our_workq_empty):
  1458.  
  1459.     movl    FALSE_REG,DISP(PSTATE_REG,SLOT(CURRENT_TASK))
  1460.     movl    FALSE_REG,DISP(PSTATE_REG,SLOT(PARENT_RET))
  1461.     movl    FALSE_REG,DISP(PSTATE_REG,SLOT(PARENT_FRAME))
  1462.     movl    FALSE_REG,DISP(PSTATE_REG,SLOT(CURRENT_DYN_ENV))
  1463.  
  1464.     moveq    IMM(INTR_LATENCY_AFTER_STEAL-1),INTR_TIMER_REG
  1465.  
  1466. #ifdef debug
  1467. /*****/    pea    PC_IND($entry)
  1468. /*****/    movl    PINC(SP),DISP(PSTATE_REG,SLOT(56))
  1469. /*****/    movl    IMM(0),DISP(PSTATE_REG,SLOT(57))
  1470. /*****/    movl    IMM(0),DISP(PSTATE_REG,SLOT(58))
  1471. #endif
  1472.  
  1473. /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
  1474. #ifdef MESSAGE_PASSING_STEAL
  1475.  
  1476. /* Prevent other processors from trying to steal from us. */
  1477.  
  1478.     movl    LTQ_TAIL_REG,DISP(PSTATE_REG,SLOT(LTQ_TAIL))
  1479.  
  1480. #ifdef SYNCHRONOUS_STEAL
  1481.  
  1482. LBL(wait_for_request):
  1483.     tstl    DISP(PSTATE_REG,SLOT(STEAL_LOCKV))
  1484.     BEQS(    no_steal)
  1485.     movl    DISP(PSTATE_REG,SLOT(THIEF)),DTEMP1
  1486.     BEQS(    wait_for_request)
  1487.     clrl    DISP(PSTATE_REG,SLOT(THIEF))
  1488.     clrl    DISP(PSTATE_REG,SLOT(STEAL_LOCKV))
  1489.     movl    DTEMP1,ATEMP1
  1490.     clrl    DISP(ATEMP1,SLOT(RESPONSE))
  1491. LBL(no_steal):
  1492.  
  1493. #endif
  1494. #endif
  1495. /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
  1496.  
  1497. LBL(try_to_steal_from_other_workq):
  1498.     movl    DISP(PSTATE_REG,SLOT(STEAL_SCAN)),PVM2_REG
  1499.     lea    DISP(PSTATE_REG,SLOT(PS+MAX_NB_PROC)),ATEMP2
  1500.     addl    PVM2_REG,ATEMP2
  1501.  
  1502. LBL(next_processor):
  1503.     subql    IMM(4),PVM2_REG
  1504.     BLEW(    scan_done)
  1505.  
  1506. LBL(check_workq):
  1507.     subql    IMM(4),ATEMP2
  1508. LBL(check_same_workq):
  1509.     movl    IND(ATEMP2),ATEMP1
  1510.     CMPL(    DISP(ATEMP1,SLOT(WORKQ_HEAD)),NULL_REG)
  1511.     BEQW(    empty_queue3)
  1512.  
  1513.     lea    DISP(ATEMP1,SLOT(WORKQ_LOCKV)),ATEMP1
  1514. LBL(lock_workq2):
  1515.     LOCK_ATEMP1(lock3)
  1516.     tstl    DISP(ATEMP1,SLOT(WORKQ_LOCKO-WORKQ_LOCKV))
  1517.     BEQS(    workq_locked)
  1518.     clrl    IND(ATEMP1)
  1519.     BRAS(    lock_workq2)
  1520. LBL(workq_locked):
  1521.     movl    DISP(ATEMP1,SLOT(WORKQ_HEAD-WORKQ_LOCKV)),PVM0_REG
  1522.     CMPL(    PVM0_REG,NULL_REG)
  1523.     BEQW(    empty_queue2)
  1524.     movl    PDEC(PVM0_REG),DTEMP1
  1525.     movl    DTEMP1,DISP(ATEMP1,SLOT(WORKQ_HEAD-WORKQ_LOCKV))
  1526.     CMPL(    DTEMP1,NULL_REG)
  1527.     BNES(    done2)
  1528.     movl    DTEMP1,DISP(ATEMP1,SLOT(WORKQ_TAIL-WORKQ_LOCKV))
  1529. LBL(done2):
  1530.  
  1531.     clrl    IND(ATEMP1)
  1532.  
  1533. /* Check if task is really READY */
  1534.  
  1535.     movl    DISP(PVM0_REG,SLOT(1)),ATEMP1
  1536.  
  1537. #ifdef MAINTAIN_TASK_STATUS
  1538.  
  1539.     CMPL(    ATEMP1,FALSE_REG)
  1540.     BEQS(    check_same_workq)
  1541.  
  1542.     lea    DISP(ATEMP1,SLOT(TASK_LOCKV)+4-SCM_type_SUBTYPED),ATEMP1
  1543. LBL(lock_task3):
  1544.     LOCK_ATEMP1(lock4)
  1545.     tstl    DISP(ATEMP1,SLOT(TASK_LOCKO-TASK_LOCKV))
  1546.     BEQS(    task_locked3)
  1547.     clrl    IND(ATEMP1)
  1548.     BRAS(    lock_task3)
  1549.  
  1550. LBL(task_not_ready3):
  1551.     clrl    IND(ATEMP1)
  1552.     BRAS(    check_same_workq)
  1553.  
  1554. LBL(task_locked3):
  1555.     movl    DISP(ATEMP1,SLOT(TASK_STATUS-TASK_LOCKV)),DTEMP1
  1556.     btst    DTEMP1,PAIR_REG
  1557.     BNES(    task_not_ready3)
  1558.  
  1559.     movl    DTEMP1,ATEMP2        /* remove task from workq */
  1560.     movl    FALSE_REG,IND(ATEMP2)
  1561.  
  1562. /* Change task's status to RUNNING */
  1563.  
  1564.     movl    PSTATE_REG,DISP(ATEMP1,SLOT(TASK_STATUS-TASK_LOCKV))
  1565.     clrl    IND(ATEMP1)
  1566.  
  1567.     lea    DISP(ATEMP1,-(SLOT(TASK_LOCKV)+4-SCM_type_SUBTYPED)),ATEMP1
  1568.  
  1569. #endif
  1570.  
  1571.     movl    PVM2_REG,DISP(PSTATE_REG,SLOT(STEAL_SCAN))
  1572.  
  1573. #ifdef debug
  1574. /*****/    movl    IMM(3),DISP(PSTATE_REG,SLOT(58))
  1575. #endif
  1576.  
  1577. LBL(resume_task):
  1578.  
  1579. /* Resume task. */
  1580.  
  1581.     movl    ATEMP1,DISP(PSTATE_REG,SLOT(CURRENT_TASK))
  1582.     movl    DISP(ATEMP1,SLOT(TASK_CONT_RET)+4-SCM_type_SUBTYPED),DISP(PSTATE_REG,SLOT(PARENT_RET))
  1583.     movl    DISP(ATEMP1,SLOT(TASK_CONT_FRAME)+4-SCM_type_SUBTYPED),DISP(PSTATE_REG,SLOT(PARENT_FRAME))
  1584.     movl    DISP(ATEMP1,SLOT(TASK_CONT_DYN_ENV)+4-SCM_type_SUBTYPED),DISP(PSTATE_REG,SLOT(CURRENT_DYN_ENV))
  1585.     movl    DISP(ATEMP1,SLOT(TASK_VALUE)+4-SCM_type_SUBTYPED),PVM1_REG
  1586.  
  1587. #ifdef debug
  1588. /*****/    pea    PC_IND($entry)
  1589. /*****/    movl    PINC(SP),DISP(PSTATE_REG,SLOT(56))
  1590. /*****/    movl    DISP(PSTATE_REG,SLOT(BOS_RET)),DISP(PSTATE_REG,SLOT(57))
  1591. #endif
  1592.  
  1593.     movl    PVM1_REG,PVM0_REG
  1594.     movl    PVM1_REG,PVM2_REG
  1595.     movl    PVM1_REG,PVM3_REG
  1596.     movl    PVM1_REG,PVM4_REG
  1597.  
  1598.     LOG(EVENT_WORKING,log2)
  1599.  
  1600.     movl    DISP(PSTATE_REG,SLOT(BOS_RET)),ATEMP1
  1601.     jmp    IND(ATEMP1)
  1602.  
  1603. LBL(empty_queue2):
  1604.     clrl    IND(ATEMP1)
  1605.     lea    DISP(ATEMP1,-SLOT(WORKQ_LOCKV)),ATEMP1
  1606. LBL(empty_queue3):
  1607.  
  1608. /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
  1609. #ifdef MESSAGE_PASSING_STEAL
  1610.  
  1611. /* Check if anything to steal. */
  1612.  
  1613.     movl    DISP(ATEMP1,SLOT(LTQ_HEAD)),DTEMP1
  1614.     CMPL(    DISP(ATEMP1,SLOT(LTQ_TAIL)),DTEMP1)
  1615.     BEQW(    next_processor)
  1616.  
  1617. #ifdef SYNCHRONOUS_STEAL
  1618.  
  1619.     movl    ATEMP1,PVM4_REG
  1620.  
  1621. /* Try to become thief. */
  1622.  
  1623.     movl    ATEMP1,DTEMP1
  1624.     addl    IMM(SLOT(STEAL_LOCKV)),DTEMP1
  1625.     READ_AND_SET_DTEMP1
  1626.     tstl    DTEMP1
  1627.     BNEW(    next_processor)
  1628.  
  1629.     movl    PVM4_REG,ATEMP1
  1630.     movl    DISP(ATEMP1,SLOT(LTQ_HEAD)),DTEMP1
  1631.     CMPL(    DISP(ATEMP1,SLOT(LTQ_TAIL)),DTEMP1)
  1632.     BNES(    we_are_thief)
  1633.  
  1634.     clrl    DISP(ATEMP1,SLOT(STEAL_LOCKV))
  1635.     BRAW(    next_processor)
  1636.  
  1637. LBL(we_are_thief):
  1638.  
  1639. /* Send steal message to victim. */
  1640.  
  1641.     movl    FALSE_REG,DISP(PSTATE_REG,SLOT(RESPONSE))
  1642.     movl    PSTATE_REG,DISP(ATEMP1,SLOT(THIEF))
  1643.     movl    IMM(-1),IND(ATEMP1)
  1644.  
  1645.     LOG(EVENT_STEALING,log3)
  1646.  
  1647. /* Wait for response. */
  1648.  
  1649.     movl    PVM2_REG,DISP(PSTATE_REG,SLOT(STEAL_SCAN))
  1650.  
  1651. LBL(wait):
  1652.     tstl    DISP(PSTATE_REG,SLOT(INTR_BARRIER))
  1653.     BEQS(    ret3)
  1654.     clrl    DISP(PSTATE_REG,SLOT(INTR_BARRIER))
  1655.     lea    PC_IND(ret3),PVM0_REG
  1656.     movl    PVM0_REG,PVM1_REG
  1657.     movl    PVM0_REG,PVM2_REG
  1658.     movl    PVM0_REG,PVM3_REG
  1659.     movl    PVM0_REG,PVM4_REG
  1660.     movl    CONST(0),ATEMP1    /* Call ##barrier */
  1661.     moveq    IMM(1),DTEMP1
  1662.     jmp    IND(ATEMP1)
  1663. RETURN(ret3,0,0):
  1664.     movl    DISP(PSTATE_REG,SLOT(RESPONSE)),ATEMP1
  1665.     CMPL(    ATEMP1,FALSE_REG)
  1666.     BEQS(    wait)
  1667.  
  1668.     clrl    DISP(PSTATE_REG,SLOT(RESPONSE))
  1669.  
  1670. #ifdef debug
  1671. /*****/    movl    ATEMP1,DISP(PSTATE_REG,SLOT(58))
  1672. #endif
  1673.  
  1674.     movl    ATEMP1,DTEMP1
  1675.     BNEW(    resume_task)
  1676.  
  1677.     LOG(EVENT_IDLE,log4)
  1678.  
  1679.     BRAW(    try_to_steal_from_other_workq)
  1680.  
  1681. #else
  1682. /* ASYNCHRONOUS_STEAL */
  1683.  
  1684.     movl    FALSE_REG,DISP(ATEMP1,SLOT(WORK_REQUEST))
  1685.     movl    IMM(-1),IND(ATEMP1)
  1686.     BRAW(    next_processor)
  1687.  
  1688. #endif
  1689.  
  1690. /*---------------------------------------------------------------------------*/
  1691. #else
  1692. /* SHARED_MEMORY_STEAL */
  1693.  
  1694. /* acquire steal_lock */
  1695.  
  1696.     movl    DISP(ATEMP1,SLOT(STEAL_LOCKO)),DTEMP1
  1697.     BNEW(    next_processor)
  1698.  
  1699.     movl    ATEMP1,PVM4_REG
  1700.  
  1701. /* Try to become thief. */
  1702.  
  1703.     movl    ATEMP1,DTEMP1
  1704.     addl    IMM(SLOT(STEAL_LOCKV)),DTEMP1
  1705.     READ_AND_SET_DTEMP1
  1706.     tstl    DTEMP1
  1707.     BNEW(    next_processor)
  1708.  
  1709.     movl    PVM4_REG,ATEMP1
  1710.  
  1711.     movl    DISP(ATEMP1,SLOT(STEAL_LOCKO)),DTEMP1
  1712.     BNES(    fail)
  1713.  
  1714.     movl    DISP(ATEMP1,SLOT(LTQ_HEAD)),PVM0_REG
  1715.     addql    IMM(4),PVM0_REG
  1716.     movl    PVM0_REG,DISP(ATEMP1,SLOT(LTQ_HEAD))
  1717.     movl    DISP(PVM0_REG,-SLOT(1)),DTEMP1
  1718.     BNES(    we_are_thief)
  1719.     subql    IMM(4),PVM0_REG
  1720.     movl    PVM0_REG,DISP(ATEMP1,SLOT(LTQ_HEAD))
  1721.  
  1722. LBL(fail):
  1723.     clrl    DISP(ATEMP1,SLOT(STEAL_LOCKV))
  1724.     BRAW(    next_processor)
  1725.  
  1726. LBL(we_are_thief):
  1727.  
  1728.     movl    PVM2_REG,DISP(PSTATE_REG,SLOT(STEAL_SCAN))
  1729.  
  1730. /* setup parent task */
  1731.  
  1732.     movl    DISP(PSTATE_REG,SLOT(TEMP_TASK)),PVM2_REG
  1733.     movl    PVM2_REG,DISP(PSTATE_REG,SLOT(CURRENT_TASK))
  1734.     movl    PVM2_REG,ATEMP2
  1735.     movl    DISP(ATEMP2,SLOT(TASK_SYNC_PH)+4-SCM_type_SUBTYPED),PVM1_REG
  1736.  
  1737. #ifdef MAINTAIN_TASK_STATUS
  1738.  
  1739. /* Link placeholder to current task so that it can get resumed when the */
  1740. /* placeholder is touched (and the task is READY). */
  1741.  
  1742.     movl    PVM1_REG,ATEMP2
  1743.     movl    DISP(ATEMP1,SLOT(CURRENT_TASK)),DISP(ATEMP2,SLOT(PH_TASK)-SCM_type_PLACEHOLDER)
  1744.  
  1745.     movl    PVM2_REG,ATEMP2
  1746.     movl    PSTATE_REG,DISP(ATEMP2,SLOT(TASK_STATUS)+4-SCM_type_SUBTYPED)
  1747.  
  1748. #endif
  1749.  
  1750. /* DTEMP1 = lazy task frame pointer */
  1751.  
  1752.     movl    DTEMP1,ATEMP2        /* get task's return address */
  1753.     movl    IND(ATEMP2),PVM3_REG
  1754.  
  1755.     movl    DISP(ATEMP1,SLOT(PARENT_RET)),DISP(PSTATE_REG,SLOT(PARENT_RET))
  1756.     movl    DISP(ATEMP1,SLOT(PARENT_FRAME)),DISP(PSTATE_REG,SLOT(PARENT_FRAME))
  1757.     movl    DISP(ATEMP1,SLOT(CURRENT_DYN_ENV)),DISP(PSTATE_REG,SLOT(CURRENT_DYN_ENV))
  1758.  
  1759.     movl    PVM3_REG,DISP(ATEMP1,SLOT(PARENT_RET))
  1760.     subql    IMM(8),PVM3_REG        /* convert return adr to normal one */
  1761.  
  1762. /* Make child's continuation frame. */
  1763.  
  1764.     movl    PVM3_REG,PDEC(HEAP_REG)
  1765.     movl    PVM2_REG,PDEC(HEAP_REG)
  1766. /* katz/weise continuations would require stolen stack frame to be put on heap
  1767.     movl    DISP(ATEMP1,SLOT(PARENT_FRAME)),PDEC(HEAP_REG)
  1768. */
  1769.     movl    FALSE_REG,PDEC(HEAP_REG)
  1770.     movl    IMM(3*0x400+(SCM_subtype_FRAME*8)),PDEC(HEAP_REG)
  1771.     lea    DISP(HEAP_REG,SCM_type_SUBTYPED),ATEMP2
  1772.  
  1773.     movl    ATEMP2,DISP(ATEMP1,SLOT(PARENT_FRAME))
  1774.  
  1775. /* copy victim's stack */
  1776.  
  1777.     movl    DISP(PVM0_REG,-SLOT(2)),PVM0_REG /* get base of continuation */
  1778.  
  1779.     movl    DTEMP1,ATEMP2
  1780.     movl    PVM0_REG,DTEMP1
  1781.     subl    ATEMP2,DTEMP1    /* DTEMP1 = length of stack area to copy */
  1782.  
  1783.     subl    DTEMP1,SP
  1784.     movl    SP,PVM0_REG
  1785.  
  1786.     lsrl    IMM(2),DTEMP1
  1787.     subql    IMM(1),DTEMP1
  1788. LBL(loop):
  1789.     movl    PINC(ATEMP2),PINC(PVM0_REG)
  1790.     DBRA(    DTEMP1,loop)
  1791.  
  1792. /* unlock steal_lock */
  1793.  
  1794.     clrl    DISP(ATEMP1,SLOT(STEAL_LOCKV))
  1795.  
  1796.     addql    IMM(8),DISP(PSTATE_REG,SLOT(COUNT1))
  1797.  
  1798.     MAKE_TEMP_TASK
  1799.  
  1800. #ifdef debug
  1801. /*****/    pea    PC_IND($entry)
  1802. /*****/    movl    PINC(SP),DISP(PSTATE_REG,SLOT(56))
  1803. /*****/    movl    PVM3_REG,DISP(PSTATE_REG,SLOT(57))
  1804. /*****/    movl    IMM(0),DISP(PSTATE_REG,SLOT(58))
  1805. #endif
  1806.  
  1807.     movl    PVM3_REG,ATEMP2
  1808.  
  1809. /* Resume task. */
  1810.  
  1811.     movl    PVM1_REG,PVM0_REG
  1812.     movl    PVM1_REG,PVM2_REG
  1813.     movl    PVM1_REG,PVM3_REG
  1814.     movl    PVM1_REG,PVM4_REG
  1815.  
  1816.     LOG(EVENT_WORKING,log5)
  1817.  
  1818.     jmp    IND(ATEMP2)
  1819.  
  1820. #endif
  1821. /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
  1822.  
  1823. LBL(scan_done):
  1824.     movl    DISP(PSTATE_REG,SLOT(NB_PROCESSORS)),PVM2_REG
  1825.     asrl    IMM(1),PVM2_REG
  1826.     movl    PVM2_REG,DISP(PSTATE_REG,SLOT(STEAL_SCAN))
  1827.  
  1828.     tstl    DISP(PSTATE_REG,SLOT(INTR_BARRIER))
  1829.     BEQS(    ret4)
  1830.     clrl    DISP(PSTATE_REG,SLOT(INTR_BARRIER))
  1831.     lea    PC_IND(ret4),PVM0_REG
  1832.     movl    PVM0_REG,PVM1_REG
  1833.     movl    PVM0_REG,PVM2_REG
  1834.     movl    PVM0_REG,PVM3_REG
  1835.     movl    PVM0_REG,PVM4_REG
  1836.     movl    CONST(0),ATEMP1    /* Call ##barrier */
  1837.     moveq    IMM(1),DTEMP1
  1838.     jmp    IND(ATEMP1)
  1839. RETURN(ret4,0,0):
  1840.  
  1841.     BRAW(    try_to_steal_from_other_workq)
  1842.  
  1843. CONSTS(1)
  1844. PRIMITIVE("##barrier")
  1845. END
  1846.  
  1847. /*---------------------------------------------------------------------------*/
  1848.  
  1849. #undef LBL
  1850. #define LBL(x)MAKE_LBL(30,x)
  1851.  
  1852. BEGIN("###_kernel.determine!")
  1853.  
  1854. #ifdef DETERMINE_IS_STRICT
  1855.     btst    PVM2_REG,PLACEHOLDER_REG
  1856.     BNES(    touched)
  1857.     movl    PVM0_REG,PDEC(SP)
  1858.     movl    PVM1_REG,PDEC(SP)
  1859.     TRAP(TOUCH_trap+2,touch,2,1)
  1860.     movl    PINC(SP),PVM1_REG
  1861.     movl    PINC(SP),PVM0_REG
  1862. LBL(touched):
  1863. #endif
  1864.  
  1865.     movl    CONST(0),ATEMP1
  1866.     jmp    IND(ATEMP1)
  1867.     
  1868. CONSTS(1)
  1869. PRIMITIVE("###_kernel.non-strict-determine!")
  1870. END
  1871.  
  1872. /*---------------------------------------------------------------------------*/
  1873.  
  1874. #undef LBL
  1875. #define LBL(x)MAKE_LBL(31,x)
  1876.  
  1877. BEGIN("###_kernel.non-strict-determine!")
  1878.  
  1879.     movl    PVM0_REG,PDEC(SP)
  1880.  
  1881.     LOG(EVENT_DETERMINE,log1)
  1882.  
  1883.     btst    PVM1_REG,PLACEHOLDER_REG
  1884.     BNES(    already_determined)
  1885.  
  1886.     movl    PVM1_REG,ATEMP2
  1887.     lea    DISP(ATEMP2,SLOT(PH_QUEUE)-SCM_type_PLACEHOLDER),ATEMP2
  1888.  
  1889.     LOCK_ATEMP2(lock1)
  1890.  
  1891.     CMPL(    DTEMP1,FALSE_REG)
  1892.     BNES(    undetermined)
  1893.     movl    DTEMP1,IND(ATEMP2)
  1894.  
  1895. LBL(already_determined):
  1896.     PREV_LOG(2,log2)
  1897.     movl    PINC(SP),PVM0_REG
  1898.     movl    CONST(0),ATEMP1    /* jump to ##exception.placeholder-already-determined */
  1899.     moveq    IMM(1),DTEMP1    /* passing 0 argument */
  1900.     jmp    IND(ATEMP1)
  1901.  
  1902. LBL(undetermined):
  1903.     movl    PVM2_REG,DISP(ATEMP2,SLOT(PH_VALUE-PH_QUEUE))
  1904.  
  1905.     movl    FALSE_REG,IND(ATEMP2)
  1906.  
  1907. /* DTEMP1 is list of tasks to restart. */
  1908.  
  1909.     btst    DTEMP1,PAIR_REG
  1910.     BNES(    tasks_restarted)
  1911.  
  1912.     movl    DTEMP1,PVM4_REG
  1913. LBL(next_task):
  1914.     movl    DTEMP1,ATEMP2
  1915.  
  1916. /* Setup task's return value. */
  1917.  
  1918.     movl    IND(ATEMP2),ATEMP1
  1919.     movl    PVM2_REG,DISP(ATEMP1,SLOT(TASK_VALUE)+4-SCM_type_SUBTYPED)
  1920.  
  1921. #ifdef MAINTAIN_TASK_STATUS
  1922.  
  1923. /* Change task's status to READY */
  1924.  
  1925.     movl    ATEMP2,DISP(ATEMP1,SLOT(TASK_STATUS)+4-SCM_type_SUBTYPED)
  1926.  
  1927. #endif
  1928.  
  1929.     movl    DISP(ATEMP2,SLOT(-1)),DTEMP1
  1930.     btst    DTEMP1,PAIR_REG
  1931.     BEQS(    next_task)
  1932.  
  1933. /* Add tasks to workq. */
  1934.  
  1935.     movl    FALSE_REG,DISP(PSTATE_REG,SLOT(WORKQ_LOCKO))
  1936. LBL(lock_workq):
  1937.     tstl    DISP(PSTATE_REG,SLOT(WORKQ_LOCKV))
  1938.     BNES(    lock_workq)
  1939.  
  1940.     movl    DISP(PSTATE_REG,SLOT(WORKQ_TAIL)),ATEMP1
  1941.     CMPL(    ATEMP1,NULL_REG)
  1942.     BNES(    non_empty_queue)
  1943.     movl    PVM4_REG,DISP(PSTATE_REG,SLOT(WORKQ_HEAD))
  1944.     BRAS(    fix_tail)
  1945. LBL(non_empty_queue):
  1946.     movl    PVM4_REG,PDEC(ATEMP1)
  1947. LBL(fix_tail):
  1948.     movl    ATEMP2,DISP(PSTATE_REG,SLOT(WORKQ_TAIL))
  1949.  
  1950.     clrl    DISP(PSTATE_REG,SLOT(WORKQ_LOCKO))
  1951.  
  1952. LBL(tasks_restarted):
  1953.     movl    PVM2_REG,PVM1_REG
  1954.     movl    PVM2_REG,PVM3_REG
  1955.     movl    PVM2_REG,PVM4_REG
  1956.     movl    PINC(SP),PVM0_REG
  1957.  
  1958.     PREV_LOG(2,log3)
  1959.  
  1960.     movl    PVM2_REG,DTEMP1 /* Required for the case of a return from a touch of d0 */
  1961.     jmp    IND(PVM0_REG)    
  1962.  
  1963. CONSTS(1)
  1964. PRIMITIVE("##exception.placeholder-already-determined")
  1965. END
  1966.  
  1967. /*---------------------------------------------------------------------------*/
  1968.  
  1969. #undef LBL
  1970. #define LBL(x)MAKE_LBL(32,x)
  1971.  
  1972. BEGIN("###_kernel.determine!-then-idle")
  1973.  
  1974.     movl    PVM0_REG,PDEC(SP)
  1975.  
  1976. #ifdef DETERMINE_IS_STRICT
  1977.     btst    PVM2_REG,PLACEHOLDER_REG
  1978.     BNES(    touched)
  1979.     movl    PVM1_REG,PDEC(SP)
  1980.     movl    PVM3_REG,PDEC(SP)
  1981.     TRAP(TOUCH_trap+2,touch,3,1)
  1982.     movl    PINC(SP),PVM3_REG
  1983.     movl    PINC(SP),PVM1_REG
  1984. LBL(touched):
  1985. #endif
  1986.  
  1987.     LOG(EVENT_DETERMINE,log1)
  1988.  
  1989.     btst    PVM1_REG,PLACEHOLDER_REG
  1990.     BNES(    already_determined)
  1991.  
  1992.     movl    PVM1_REG,ATEMP2
  1993.     lea    DISP(ATEMP2,SLOT(PH_QUEUE)-SCM_type_PLACEHOLDER),ATEMP2
  1994.  
  1995.     LOCK_ATEMP2(lock1)
  1996.  
  1997.     CMPL(    DTEMP1,FALSE_REG)
  1998.     BNES(    undetermined)
  1999.     movl    DTEMP1,IND(ATEMP2)
  2000.  
  2001. LBL(already_determined):
  2002.     PREV_LOG(2,log2)
  2003.     movl    PINC(SP),PVM0_REG
  2004.     movl    CONST(1),ATEMP1    /* jump to ##exception.placeholder-already-determined */
  2005.     moveq    IMM(1),DTEMP1    /* passing 0 argument */
  2006.     jmp    IND(ATEMP1)
  2007.  
  2008. LBL(no_task_to_restart):
  2009.     movl    PVM3_REG,PVM1_REG
  2010.     movl    CONST(0),ATEMP1
  2011.     jmp    IND(ATEMP1)
  2012.  
  2013. LBL(undetermined):
  2014.     movl    PINC(SP),PVM0_REG
  2015.  
  2016.     movl    PVM2_REG,DISP(ATEMP2,SLOT(PH_VALUE-PH_QUEUE))
  2017.  
  2018.     movl    FALSE_REG,IND(ATEMP2)
  2019.  
  2020. #ifdef MAINTAIN_TASK_STATUS
  2021.  
  2022. /* Change task's status to DEAD */
  2023.  
  2024.     movl    DISP(PSTATE_REG,SLOT(CURRENT_TASK)),ATEMP1
  2025.     movl    FALSE_REG,DISP(ATEMP1,SLOT(TASK_STATUS)+4-SCM_type_SUBTYPED)
  2026.  
  2027. #endif
  2028.  
  2029. /* DTEMP1 is list of tasks to restart. */
  2030.  
  2031.     btst    DTEMP1,PAIR_REG
  2032.     BNES(    no_task_to_restart)
  2033.  
  2034.     movl    DTEMP1,ATEMP2
  2035.     movl    IND(ATEMP2),PVM3_REG
  2036.     movl    PDEC(ATEMP2),DTEMP1
  2037.     btst    DTEMP1,PAIR_REG
  2038.     BNES(    tasks_restarted)
  2039.  
  2040.     movl    DTEMP1,PVM4_REG
  2041. LBL(next_task):
  2042.     movl    DTEMP1,ATEMP2
  2043.  
  2044. /* Setup task's return value. */
  2045.  
  2046.     movl    IND(ATEMP2),ATEMP1
  2047.     movl    PVM2_REG,DISP(ATEMP1,SLOT(TASK_VALUE)+4-SCM_type_SUBTYPED)
  2048.  
  2049. #ifdef MAINTAIN_TASK_STATUS
  2050.  
  2051. /* Change task's status to READY */
  2052.  
  2053.     movl    ATEMP2,DISP(ATEMP1,SLOT(TASK_STATUS)+4-SCM_type_SUBTYPED)
  2054.  
  2055. #endif
  2056.  
  2057.     movl    DISP(ATEMP2,SLOT(-1)),DTEMP1
  2058.     btst    DTEMP1,PAIR_REG
  2059.     BEQS(    next_task)
  2060.  
  2061. /* Add tasks to workq. */
  2062.  
  2063.     movl    FALSE_REG,DISP(PSTATE_REG,SLOT(WORKQ_LOCKO))
  2064. LBL(lock_workq):
  2065.     tstl    DISP(PSTATE_REG,SLOT(WORKQ_LOCKV))
  2066.     BNES(    lock_workq)
  2067.  
  2068.     movl    DISP(PSTATE_REG,SLOT(WORKQ_TAIL)),ATEMP1
  2069.     CMPL(    ATEMP1,NULL_REG)
  2070.     BNES(    non_empty_queue)
  2071.     movl    PVM4_REG,DISP(PSTATE_REG,SLOT(WORKQ_HEAD))
  2072.     BRAS(    fix_tail)
  2073. LBL(non_empty_queue):
  2074.     movl    PVM4_REG,PDEC(ATEMP1)
  2075. LBL(fix_tail):
  2076.     movl    ATEMP2,DISP(PSTATE_REG,SLOT(WORKQ_TAIL))
  2077.  
  2078.     clrl    DISP(PSTATE_REG,SLOT(WORKQ_LOCKO))
  2079.  
  2080. LBL(tasks_restarted):
  2081.  
  2082.     movl    PVM3_REG,ATEMP1
  2083.  
  2084. #ifdef MAINTAIN_TASK_STATUS
  2085.  
  2086. /* Change task's status to RUNNING */
  2087.  
  2088.     movl    PSTATE_REG,DISP(ATEMP1,SLOT(TASK_STATUS)+4-SCM_type_SUBTYPED)
  2089.  
  2090. #endif
  2091.  
  2092. /* Resume task. */
  2093.  
  2094.     movl    ATEMP1,DISP(PSTATE_REG,SLOT(CURRENT_TASK))
  2095.     movl    DISP(ATEMP1,SLOT(TASK_CONT_RET)+4-SCM_type_SUBTYPED),DISP(PSTATE_REG,SLOT(PARENT_RET))
  2096.     movl    DISP(ATEMP1,SLOT(TASK_CONT_FRAME)+4-SCM_type_SUBTYPED),DISP(PSTATE_REG,SLOT(PARENT_FRAME))
  2097.     movl    DISP(ATEMP1,SLOT(TASK_CONT_DYN_ENV)+4-SCM_type_SUBTYPED),DISP(PSTATE_REG,SLOT(CURRENT_DYN_ENV))
  2098.  
  2099. #ifdef debug
  2100. /*****/    pea    PC_IND($entry)
  2101. /*****/    movl    PINC(SP),DISP(PSTATE_REG,SLOT(56))
  2102. /*****/    movl    DISP(PSTATE_REG,SLOT(BOS_RET)),DISP(PSTATE_REG,SLOT(57))
  2103. /*****/    movl    IMM(0),DISP(PSTATE_REG,SLOT(58))
  2104. #endif
  2105.  
  2106.     movl    PVM2_REG,PVM1_REG
  2107.     movl    PVM1_REG,PVM0_REG
  2108.     movl    PVM1_REG,PVM3_REG
  2109.     movl    PVM1_REG,PVM4_REG
  2110.  
  2111.     LOG(EVENT_WORKING,log3)
  2112.  
  2113.     movl    DISP(PSTATE_REG,SLOT(BOS_RET)),ATEMP1
  2114.     jmp    IND(ATEMP1)
  2115.  
  2116. CONSTS(2)
  2117. PRIMITIVE("###_kernel.idle")
  2118. PRIMITIVE("##exception.placeholder-already-determined")
  2119. END
  2120.  
  2121. /*---------------------------------------------------------------------------*/
  2122.  
  2123. #undef LBL
  2124. #define LBL(x)MAKE_LBL(33,x)
  2125.  
  2126. BEGIN("###_kernel.touch")
  2127.  
  2128.     movl    PVM0_REG,PDEC(SP)
  2129.     movl    ATEMP2,PVM4_REG
  2130.  
  2131. /* Check if the placeholder was generated by a DELAY. */
  2132.  
  2133.     tstl    DISP(ATEMP2,SLOT(PH_DELAY)-SCM_type_PLACEHOLDER)
  2134.     BEQS(    not_delay_ph2)
  2135.  
  2136.     lea    DISP(ATEMP2,SLOT(PH_QUEUE)-SCM_type_PLACEHOLDER),ATEMP2
  2137.  
  2138.     LOCK_ATEMP2(lock1)
  2139.  
  2140.     movl    DISP(ATEMP2,SLOT(PH_DELAY)-SLOT(PH_QUEUE)),PVM1_REG
  2141.     BEQS(    not_delay_ph1)
  2142.  
  2143.     clrl    DISP(ATEMP2,SLOT(PH_DELAY)-SLOT(PH_QUEUE))
  2144.     movl    DTEMP1,IND(ATEMP2)
  2145.  
  2146.     movl    PVM4_REG,PDEC(SP)
  2147.  
  2148. /* Restore delayed computation. */
  2149.  
  2150.     subql    IMM(SCM_type_SUBTYPED),PVM1_REG
  2151.     movl    PVM1_REG,ATEMP1
  2152.  
  2153.     movl    PINC(ATEMP1),DTEMP1
  2154.     lsrl    IMM(8),DTEMP1
  2155.     subql    IMM(4),DTEMP1
  2156.     subl    DTEMP1,SP
  2157.     lsrl    IMM(2),DTEMP1
  2158.  
  2159.     movl    PINC(ATEMP1),PVM0_REG
  2160.     subql    IMM(1),DTEMP1
  2161.     movl    SP,ATEMP2
  2162. LBL(copy):
  2163.     movl    PINC(ATEMP1),PINC(ATEMP2)
  2164.     DBRA(    DTEMP1,copy)
  2165.  
  2166.     lea    PC_IND(ret1),ATEMP1
  2167.  
  2168.     moveq    IMM(0),PVM1_REG
  2169.     movw    DISP(PVM0_REG,-4),PVM1_REG    /* get link */
  2170.     movl    ATEMP1,INXW(SP,PVM1_REG,0)
  2171.  
  2172.     PREV_LOG(2,log1)
  2173.  
  2174.     movl    PVM2_REG,PVM1_REG
  2175.     jmp    IND(PVM0_REG)
  2176. RETURN(ret1,2,1):
  2177.  
  2178.     movl    PVM1_REG,PVM2_REG
  2179.     movl    PINC(SP),PVM1_REG
  2180.     movl    PINC(SP),PVM0_REG
  2181.  
  2182.     movl    CONST(3),ATEMP1    /* jump to ###_kernel.determine! */
  2183.     jmp    IND(ATEMP1)
  2184.  
  2185. LBL(not_delay_ph1):
  2186.     movl    DTEMP1,IND(ATEMP2)
  2187.  
  2188. LBL(not_delay_ph2):
  2189.  
  2190. /* Call ###_kernel.transfer-lazy-tasks-to-heap. */
  2191.  
  2192.     pea    PC_IND(ret2)
  2193.     movl    CONST(0),ATEMP1
  2194.     jmp    IND(ATEMP1)
  2195. RETURN(ret2,1,1):
  2196.  
  2197. /* Call ###_kernel.transfer-stack-to-heap. */
  2198.  
  2199. /* ###_kernel.transfer-lazy-tasks-to-heap has reserved enough */
  2200. /* space, so no GC check required.                            */
  2201.  
  2202.     pea    PC_IND(ret3)
  2203.     movl    CONST(1),ATEMP1
  2204.     jmp    IND(ATEMP1)
  2205. LBL(ret3):
  2206.  
  2207. /* Save state of current task. */
  2208.  
  2209.     movl    DISP(PSTATE_REG,SLOT(CURRENT_TASK)),ATEMP1
  2210.  
  2211.     movl    PINC(SP),PVM0_REG
  2212.     movl    PVM0_REG,DISP(ATEMP1,SLOT(TASK_CONT_RET)+4-SCM_type_SUBTYPED)
  2213.     movl    PVM2_REG,DISP(ATEMP1,SLOT(TASK_CONT_FRAME)+4-SCM_type_SUBTYPED)
  2214.     movl    DISP(PSTATE_REG,SLOT(CURRENT_DYN_ENV)),DISP(ATEMP1,SLOT(TASK_CONT_DYN_ENV)+4-SCM_type_SUBTYPED)
  2215.     movl    FALSE_REG,DISP(ATEMP1,SLOT(TASK_VALUE)+4-SCM_type_SUBTYPED)
  2216.  
  2217.     movl    ATEMP1,PDEC(HEAP_REG)
  2218.     movl    HEAP_REG,PVM3_REG
  2219.  
  2220. /* Final check for determinedness. */
  2221.  
  2222.     btst    PVM4_REG,PLACEHOLDER_REG
  2223.     BNES(    already_determined)
  2224.  
  2225.     movl    PVM4_REG,ATEMP2
  2226.     lea    DISP(ATEMP2,SLOT(PH_QUEUE)-SCM_type_PLACEHOLDER),ATEMP2
  2227.  
  2228.     LOCK_ATEMP2(lock2)
  2229.  
  2230.     CMPL(    DTEMP1,FALSE_REG)
  2231.     BNES(    undetermined)
  2232.  
  2233.     movl    DTEMP1,IND(ATEMP2)
  2234.     movl    DISP(ATEMP2,SLOT(PH_VALUE-PH_QUEUE)),PVM4_REG
  2235.  
  2236. LBL(already_determined):
  2237.     addql    IMM(4),HEAP_REG
  2238.  
  2239. /* Resume task. */
  2240.  
  2241.     movl    DISP(PSTATE_REG,SLOT(CURRENT_TASK)),ATEMP2
  2242.     movl    DISP(ATEMP2,SLOT(TASK_CONT_RET)+4-SCM_type_SUBTYPED),DISP(PSTATE_REG,SLOT(PARENT_RET))
  2243.     movl    DISP(ATEMP2,SLOT(TASK_CONT_FRAME)+4-SCM_type_SUBTYPED),DISP(PSTATE_REG,SLOT(PARENT_FRAME))
  2244.     movl    DISP(ATEMP2,SLOT(TASK_CONT_DYN_ENV)+4-SCM_type_SUBTYPED),DISP(PSTATE_REG,SLOT(CURRENT_DYN_ENV))
  2245.  
  2246. #ifdef debug
  2247. /*****/    pea    PC_IND($entry)
  2248. /*****/    movl    PINC(SP),DISP(PSTATE_REG,SLOT(56))
  2249. /*****/    movl    DISP(PSTATE_REG,SLOT(BOS_RET)),DISP(PSTATE_REG,SLOT(57))
  2250. /*****/    movl    IMM(0),DISP(PSTATE_REG,SLOT(58))
  2251. #endif
  2252.  
  2253.     movl    PVM4_REG,PVM0_REG
  2254.     movl    PVM4_REG,PVM1_REG
  2255.     movl    PVM4_REG,PVM2_REG
  2256.     movl    PVM4_REG,PVM3_REG
  2257.  
  2258.     PREV_LOG(2,log2)
  2259.  
  2260.     movl    DISP(PSTATE_REG,SLOT(BOS_RET)),ATEMP1
  2261.     jmp    IND(ATEMP1)
  2262.  
  2263. LBL(undetermined):
  2264.     movl    DTEMP1,PDEC(HEAP_REG)
  2265.     movl    PVM3_REG,IND(ATEMP2)
  2266.  
  2267.     addql    IMM(8),DISP(PSTATE_REG,SLOT(COUNT2))
  2268.  
  2269. #ifdef MAINTAIN_TASK_STATUS
  2270.  
  2271. /* Change task's status to WAITING */
  2272.  
  2273.     movl    DISP(PSTATE_REG,SLOT(CURRENT_TASK)),ATEMP1
  2274.     movl    NULL_REG,DISP(ATEMP1,SLOT(TASK_STATUS)+4-SCM_type_SUBTYPED)
  2275.  
  2276. /* Resume placeholder's task if possible (i.e. if it is READY) */
  2277.  
  2278.     movl    DISP(ATEMP2,SLOT(PH_TASK-PH_QUEUE)),PVM1_REG
  2279.     movl    CONST(2),ATEMP1
  2280.     jmp    IND(ATEMP1)
  2281.  
  2282. #else
  2283.  
  2284.     moveq    IMM(0),PVM1_REG
  2285.     movl    CONST(2),ATEMP1
  2286.     jmp    IND(ATEMP1)
  2287.  
  2288. #endif
  2289.  
  2290. CONSTS(4)
  2291. PRIMITIVE("###_kernel.transfer-lazy-tasks-to-heap")
  2292. PRIMITIVE("###_kernel.transfer-stack-to-heap")
  2293. PRIMITIVE("###_kernel.idle")
  2294. PRIMITIVE("###_kernel.determine!")
  2295. END
  2296.  
  2297. /*---------------------------------------------------------------------------*/
  2298.  
  2299. #undef LBL
  2300. #define LBL(x)MAKE_LBL(34,x)
  2301.  
  2302. BEGIN("###_kernel.transfer-lazy-task-chunk-to-heap")
  2303.  
  2304. /* On entry:                                                       */
  2305. /*   top of stack = exit address                                   */
  2306. /*   PVM2_REG = processor to respond to or task list               */
  2307. /*   PVM3_REG = stack base                                         */
  2308. /*   ATEMP1 = LTQ_HEAD                                             */
  2309.  
  2310. /* On exit:                                                        */
  2311. /*   PVM2_REG = new task list                                      */
  2312. /*   PVM4_REG preserved                                            */
  2313. /*   PVM0_REG, PVM1_REG, PVM3_REG, DTEMP1, ATEMP1, ATEMP2 modified */
  2314.  
  2315. /* It is assumed that:                                                 */
  2316. /*   - there is at least one lazy task on the lazy task queue          */
  2317. /*   - no GC will be required (there is enough free space in the heap) */
  2318.  
  2319. #ifndef MESSAGE_PASSING_STEAL
  2320.     movl    ATEMP1,PVM1_REG
  2321. #endif
  2322.  
  2323.     addql    IMM(4),ATEMP1    /* adjust LTQ_HEAD as though taking one task */
  2324.  
  2325.     lea    DISP(LTQ_TAIL_REG,-SLOT(MIN_VICTIM_TASKS)),PVM0_REG
  2326.  
  2327.     CMPL(    ATEMP1,PVM0_REG)
  2328.     BLSS(    found_split_point2)
  2329.  
  2330.     movl    DISP(PVM0_REG,-SLOT(1)),DTEMP1
  2331.  
  2332.     movl    PVM3_REG,ATEMP2
  2333.     lea    DISP(ATEMP2,-SLOT(MAX_TASK_FRAME_CHUNK_SIZE)),ATEMP2
  2334.  
  2335.     CMPL(    DTEMP1,ATEMP2)
  2336.     BLSS(    found_split_point1)
  2337.  
  2338. LBL(loop1):
  2339.     CMPL(    PINC(ATEMP1),ATEMP2)
  2340.     BLSS(    loop1)
  2341.  
  2342.     subql    IMM(4),ATEMP1
  2343.     BRAS(    found_split_point2)
  2344.  
  2345. LBL(found_split_point1):
  2346.     movl    PVM0_REG,ATEMP1
  2347. LBL(found_split_point2):
  2348.  
  2349. #ifndef MESSAGE_PASSING_STEAL
  2350.     movl    PVM1_REG,ATEMP2
  2351. LBL(loop2):
  2352.     addql    IMM(4),ATEMP2
  2353.     clrl    DISP(ATEMP2,-SLOT(2))
  2354.     CMPL(    ATEMP2,ATEMP1)
  2355.     BNES(    loop2)
  2356. #endif
  2357.  
  2358.     movl    CONST(0),ATEMP2
  2359.     jmp    IND(ATEMP2)
  2360.  
  2361. CONSTS(1)
  2362. PRIMITIVE("###_kernel.transfer-lazy-task-to-heap")
  2363. END
  2364.  
  2365. /*---------------------------------------------------------------------------*/
  2366.  
  2367. #undef LBL
  2368. #define LBL(x)MAKE_LBL(35,x)
  2369.  
  2370. BEGIN("###_kernel.transfer-lazy-task-to-heap")
  2371.  
  2372. /* On entry:                                                       */
  2373. /*   top of stack = exit address                                   */
  2374. /*   PVM2_REG = processor to respond to or task list               */
  2375. /*   PVM3_REG = stack base                                         */
  2376. /*   ATEMP1 = LTQ split point                                      */
  2377.  
  2378. /* On exit:                                                        */
  2379. /*   PVM2_REG = new task list                                      */
  2380. /*   PVM4_REG preserved                                            */
  2381. /*   PVM0_REG, PVM1_REG, PVM3_REG, DTEMP1, ATEMP1, ATEMP2 modified */
  2382.  
  2383. /* It is assumed that:                                                 */
  2384. /*   - there is at least one lazy task on the lazy task queue          */
  2385. /*   - no GC will be required (there is enough free space in the heap) */
  2386.  
  2387.     movl    ATEMP1,DISP(PSTATE_REG,SLOT(LTQ_HEAD))
  2388.     movl    DISP(ATEMP1,-SLOT(1)),ATEMP2
  2389.     movl    IND(ATEMP2),DTEMP1
  2390.  
  2391. /* DTEMP1 = task's return adr, ATEMP2 = task boundary */
  2392.  
  2393. /* Now, we must replace the child's return address with the 'bottom of stack'*/
  2394. /* return address.  Because we don't really know where the return address    */
  2395. /* is (but we do know its value) we must scan the child's stack until we     */
  2396. /* have found the address.                                                   */
  2397.  
  2398.     movl    ATEMP2,ATEMP1
  2399. LBL(loop1):
  2400.     CMPL(    PDEC(ATEMP1),DTEMP1)
  2401.     BNES(    loop1)
  2402.  
  2403.     movl    DISP(PSTATE_REG,SLOT(BOS_RET)),PVM0_REG
  2404.     movl    PVM0_REG,IND(ATEMP1)
  2405.  
  2406. /* Similarly, replace 'bottom of stack' return address by correct one */
  2407.  
  2408.     movl    PVM3_REG,ATEMP1
  2409. LBL(loop2):
  2410.     CMPL(    PDEC(ATEMP1),PVM0_REG)
  2411.     BNES(    loop2)
  2412.  
  2413.     movl    DISP(PSTATE_REG,SLOT(PARENT_RET)),IND(ATEMP1)
  2414.  
  2415. /* Next, we must find the dynamic environment of the parent. */
  2416.  
  2417.     movl    DISP(PSTATE_REG,SLOT(CURRENT_DYN_ENV)),PDEC(SP) /*guard*/
  2418.     movl    DISP(PSTATE_REG,SLOT(DEQ_TAIL)),PVM0_REG
  2419.     movl    SP,PDEC(PVM0_REG)
  2420.  
  2421.     movl    DISP(PSTATE_REG,SLOT(DEQ_HEAD)),PVM0_REG
  2422. LBL(loop3):
  2423.     CMPL(    PDEC(PVM0_REG),ATEMP2)
  2424.     BCSS(    loop3)
  2425.  
  2426.     addql    IMM(4),PVM0_REG
  2427.     movl    PVM0_REG,DISP(PSTATE_REG,SLOT(DEQ_HEAD))
  2428.  
  2429. /* Setup parent task. */
  2430.  
  2431.     movl    DISP(PSTATE_REG,SLOT(TEMP_TASK)),ATEMP1
  2432.     movl    PDEC(PVM0_REG),PVM0_REG
  2433.     movl    IND(PVM0_REG),DISP(ATEMP1,SLOT(TASK_CONT_DYN_ENV)+4-SCM_type_SUBTYPED)
  2434.     subql    IMM(8),DTEMP1        /* convert return adr to normal one */
  2435.     movl    DTEMP1,DISP(ATEMP1,SLOT(TASK_CONT_RET)+4-SCM_type_SUBTYPED)
  2436.  
  2437. #ifdef MAINTAIN_TASK_STATUS
  2438.  
  2439. /* Link placeholder to current task so that it can get resumed when the */
  2440. /* placeholder is touched (and the task is READY). */
  2441.  
  2442.     movl    DISP(ATEMP1,SLOT(TASK_SYNC_PH)+4-SCM_type_SUBTYPED),PVM0_REG
  2443.     movl    DISP(PSTATE_REG,SLOT(CURRENT_TASK)),DISP(PVM0_REG,SLOT(PH_TASK)-SCM_type_PLACEHOLDER)
  2444.  
  2445. #endif
  2446.  
  2447.     addql    IMM(4),SP
  2448.  
  2449. /* Allocate a single frame object for task's continuation */
  2450.  
  2451. /* Compute size of frame object */
  2452.  
  2453.     subl    ATEMP2,PVM3_REG
  2454.     addql    IMM(4),PVM3_REG
  2455.  
  2456. /* Allocate frame object. */
  2457.  
  2458.     movl    PVM3_REG,PVM1_REG
  2459.     addw    IMM(11),PVM1_REG
  2460.     andw    IMM(-8),PVM1_REG
  2461.     subl    PVM1_REG,HEAP_REG
  2462.     asll    IMM(8),PVM3_REG
  2463.     movb    IMM(SCM_subtype_FRAME*8),PVM3_REG
  2464.     movl    PVM3_REG,IND(HEAP_REG)
  2465.  
  2466.     clrl    DISP(HEAP_REG,SLOT(1))
  2467.     lea    DISP(HEAP_REG,SCM_type_SUBTYPED),PVM0_REG
  2468.     movl    PVM0_REG,DISP(ATEMP1,SLOT(TASK_CONT_FRAME)+4-SCM_type_SUBTYPED)
  2469.  
  2470. /* Make child's continuation frame. */
  2471.  
  2472.     movl    DTEMP1,PDEC(HEAP_REG)
  2473.     movl    ATEMP1,PDEC(HEAP_REG)
  2474.     movl    PVM0_REG,PDEC(HEAP_REG)
  2475.     movl    IMM(3*0x400+(SCM_subtype_FRAME*8)),PDEC(HEAP_REG)
  2476.  
  2477.     movl    PVM0_REG,DTEMP1
  2478.  
  2479. /* Check were parent task should go. */
  2480.  
  2481.     movl    PVM2_REG,PVM1_REG
  2482.     BEQS(    transfer_to_workq)
  2483.  
  2484. /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
  2485. #ifdef MESSAGE_PASSING_STEAL
  2486. #ifdef SYNCHRONOUS_STEAL
  2487.  
  2488.     andw    IMM(7),PVM2_REG
  2489.     BNES(    transfer_to_task_list)
  2490.  
  2491. LBL(transfer_to_thief):
  2492.  
  2493. /* Transfer task to thief processor. */
  2494.  
  2495.     movl    PVM1_REG,PVM0_REG
  2496.  
  2497. #ifdef MAINTAIN_TASK_STATUS
  2498.  
  2499. /* Change task's status to RUNNING */
  2500.  
  2501.     movl    PVM0_REG,DISP(ATEMP1,SLOT(TASK_STATUS)+4-SCM_type_SUBTYPED)
  2502.  
  2503. #endif
  2504.  
  2505.     movl    ATEMP1,DISP(PVM0_REG,SLOT(RESPONSE))
  2506.  
  2507.     BRAS(    copy_stack)
  2508.  
  2509. LBL(transfer_to_task_list):
  2510.  
  2511. #endif
  2512. #endif
  2513. /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
  2514.  
  2515. /* Add parent task to head of task list. */
  2516.  
  2517.     movl    ATEMP1,PDEC(HEAP_REG)
  2518.  
  2519. #ifdef MAINTAIN_TASK_STATUS
  2520.  
  2521. /* Change task's status to READY */
  2522.  
  2523.     movl    HEAP_REG,DISP(ATEMP1,SLOT(TASK_STATUS)+4-SCM_type_SUBTYPED)
  2524.  
  2525. #endif
  2526.  
  2527.     movl    HEAP_REG,PVM2_REG
  2528.     movl    PVM1_REG,PDEC(HEAP_REG)
  2529.  
  2530.     BRAS(    copy_stack)
  2531.  
  2532. LBL(transfer_to_workq):
  2533.  
  2534. /* Add parent task to workq. */
  2535.  
  2536.     movl    ATEMP1,PDEC(HEAP_REG)
  2537.  
  2538. #ifdef MAINTAIN_TASK_STATUS
  2539.  
  2540. /* Change task's status to READY */
  2541.  
  2542.     movl    HEAP_REG,DISP(ATEMP1,SLOT(TASK_STATUS)+4-SCM_type_SUBTYPED)
  2543.  
  2544. #endif
  2545.  
  2546.     movl    FALSE_REG,DISP(PSTATE_REG,SLOT(WORKQ_LOCKO))
  2547. LBL(lock_workq):
  2548.     tstl    DISP(PSTATE_REG,SLOT(WORKQ_LOCKV))
  2549.     BNES(    lock_workq)
  2550.  
  2551.     movl    DISP(PSTATE_REG,SLOT(WORKQ_TAIL)),ATEMP1
  2552.     CMPL(    ATEMP1,NULL_REG)
  2553.     BNES(    non_empty_queue)
  2554.     movl    HEAP_REG,DISP(PSTATE_REG,SLOT(WORKQ_HEAD))
  2555.     BRAS(    fix_tail)
  2556. LBL(non_empty_queue):
  2557.     movl    HEAP_REG,PDEC(ATEMP1)
  2558. LBL(fix_tail):
  2559.     movl    HEAP_REG,DISP(PSTATE_REG,SLOT(WORKQ_TAIL))
  2560.  
  2561.     movl    NULL_REG,PDEC(HEAP_REG)
  2562.  
  2563.     clrl    DISP(PSTATE_REG,SLOT(WORKQ_LOCKO))
  2564.  
  2565. LBL(copy_stack):
  2566.  
  2567. /* Copy stack to frame object. */
  2568.  
  2569. /* PVM3_REG=frame_header, ATEMP2=start_of_stack, DTEMP1=frame_object */
  2570.  
  2571.     lsrl    IMM(8),PVM3_REG
  2572.     lsrl    IMM(2),PVM3_REG
  2573.     subql    IMM(2),PVM3_REG
  2574.  
  2575.     movl    DTEMP1,ATEMP1
  2576.     addql    IMM(SLOT(2)-SCM_type_SUBTYPED),ATEMP1
  2577. LBL(copy_loop):
  2578.     movl    PINC(ATEMP2),PINC(ATEMP1)
  2579.     DBRA(    PVM3_REG,copy_loop)
  2580.  
  2581.     movl    DTEMP1,ATEMP1
  2582.     movl    DISP(PSTATE_REG,SLOT(PARENT_FRAME)),DISP(ATEMP1,SLOT(1)-SCM_type_SUBTYPED)
  2583.  
  2584. /* Setup new parent continuation. */
  2585.  
  2586.     lea    DISP(ATEMP1,-SLOT(4)),ATEMP1
  2587.     movl    ATEMP1,DISP(PSTATE_REG,SLOT(PARENT_FRAME))
  2588.     movl    CONST(0),ATEMP1
  2589.     addw    IMM(16),ATEMP1
  2590.     movl    ATEMP1,DISP(PSTATE_REG,SLOT(PARENT_RET))
  2591.  
  2592. #ifdef debug
  2593. /*****/    pea    PC_IND($entry)
  2594. /*****/    movl    PINC(SP),DISP(PSTATE_REG,SLOT(56))
  2595. /*****/    movl    IND(SP),DISP(PSTATE_REG,SLOT(57))
  2596. /*****/    movl    IMM(0),DISP(PSTATE_REG,SLOT(58))
  2597. #endif
  2598.  
  2599. /* Return. */
  2600.  
  2601.     addql    IMM(8),DISP(PSTATE_REG,SLOT(COUNT1))
  2602.  
  2603.     MAKE_TEMP_TASK
  2604.  
  2605.     rts
  2606.  
  2607. CONSTS(1)
  2608. PRIMITIVE("###_kernel.task")
  2609. END
  2610.  
  2611. /*---------------------------------------------------------------------------*/
  2612.  
  2613. #undef LBL
  2614. #define LBL(x)MAKE_LBL(36,x)
  2615.  
  2616. BEGIN("###_kernel.task")
  2617.  
  2618. /* This is the code that is run every time the child's continuation is */
  2619. /* returned from.                                                      */
  2620.  
  2621. RETURN(child_ret,2,1):
  2622.  
  2623. /* First, check if this is the first return from the child. */
  2624.  
  2625.     movl    IND(SP),ATEMP2        /* ATEMP2 = parent task */
  2626.     movl    PVM1_REG,PDEC(SP)
  2627.     movl    ATEMP2,DTEMP1
  2628.     addl    IMM(SLOT(TASK_SYNC_PH)+4-SCM_type_SUBTYPED),DTEMP1
  2629.     READ_AND_CLEAR_DTEMP1
  2630.     btst    DTEMP1,PLACEHOLDER_REG
  2631.     BNES(    not_first_ret)
  2632.  
  2633. /* If it is the first return, determine the synchronization placeholder */
  2634. /* and propagate the legitimacy.                                        */
  2635.  
  2636.     movl    DTEMP1,PDEC(SP)
  2637.  
  2638. #ifdef LEGITIMACY
  2639.  
  2640.     movl    DISP(ATEMP2,SLOT(TASK_LEGIT)+4-SCM_type_SUBTYPED),PVM1_REG
  2641.  
  2642. /* Legitimacy placeholders can be determined with placeholders.        */
  2643. /* So, it is wise to chase the placeholder before doing the determine. */
  2644.  
  2645.     movl    DISP(PSTATE_REG,SLOT(CURRENT_TASK)),ATEMP2
  2646.     movl    DISP(ATEMP2,SLOT(TASK_LEGIT)+4-SCM_type_SUBTYPED),PVM2_REG
  2647. LBL(next):
  2648.     btst    PVM2_REG,PLACEHOLDER_REG
  2649.     BNES(    end_of_chase)
  2650.     movl    PVM2_REG,ATEMP1
  2651.     movl    DISP(ATEMP1,SLOT(PH_VALUE)-SCM_type_PLACEHOLDER),PVM2_REG
  2652.     CMPL(    ATEMP1,PVM2_REG)
  2653.     BNES(    next)
  2654.  
  2655. LBL(end_of_chase):
  2656.     lea    PC_IND(ret),PVM0_REG
  2657.     movl    CONST(0),ATEMP1
  2658.     jmp    IND(ATEMP1)
  2659. RETURN(ret,4,1):
  2660.  
  2661. #endif
  2662.  
  2663. /* Determine value placeholder */
  2664.  
  2665.     movl    PINC(SP),PVM1_REG
  2666.     movl    PINC(SP),PVM2_REG
  2667.     movl    PINC(SP),PVM3_REG
  2668.     movl    PINC(SP),PVM0_REG
  2669.     movl    CONST(1),ATEMP1
  2670.     jmp    IND(ATEMP1)
  2671.  
  2672. LBL(not_first_ret):
  2673.     movl    PINC(SP),PVM1_REG
  2674.     addql    IMM(4),SP
  2675.     rts
  2676.  
  2677. CONSTS(2)
  2678. PRIMITIVE("###_kernel.non-strict-determine!")
  2679. PRIMITIVE("###_kernel.determine!-then-idle")
  2680. END
  2681.  
  2682. /*---------------------------------------------------------------------------*/
  2683.  
  2684. #undef LBL
  2685. #define LBL(x)MAKE_LBL(37,x)
  2686.  
  2687. BEGIN("###_kernel.transfer-lazy-tasks-to-heap")
  2688.  
  2689. /* On entry:                                               */
  2690. /*   top of stack = exit address                           */
  2691.  
  2692. /* On exit:                                                */
  2693. /*   PVM2_REG = task list                                  */
  2694. /*   PVM4_REG preserved                                    */
  2695. /*   PVM0_REG, PVM1_REG, PVM3_REG, DTEMP1, ATEMP2 modified */
  2696.  
  2697. /* We must make sure that there is enough free space for all the frames (so  */
  2698. /* that we can avoid to check for GC on every one).  If each frame is copied */
  2699. /* independently, the heap space required could be as much as 4 times the    */
  2700. /* space used on the stack plus a certain amount for every lazy task.        */
  2701.  
  2702. #ifndef MESSAGE_PASSING_STEAL
  2703.     movl    FALSE_REG,DISP(PSTATE_REG,SLOT(STEAL_LOCKO))
  2704. LBL(lock_steal1):
  2705.     tstl    DISP(PSTATE_REG,SLOT(STEAL_LOCKV))
  2706.     BNES(    lock_steal1)
  2707.     movl    DISP(PSTATE_REG,SLOT(LTQ_HEAD)),ATEMP1
  2708.     movl    DISP(ATEMP1,-SLOT(1)),DTEMP1
  2709.     clrl    DISP(PSTATE_REG,SLOT(STEAL_LOCKO))
  2710. #else
  2711.     movl    DISP(PSTATE_REG,SLOT(LTQ_HEAD)),ATEMP1
  2712.     movl    DISP(ATEMP1,-SLOT(1)),DTEMP1
  2713. #endif
  2714.     subl    SP,DTEMP1
  2715.     asll    IMM(2),DTEMP1
  2716.  
  2717.     movl    LTQ_TAIL_REG,PVM1_REG
  2718.     subl    ATEMP1,PVM1_REG
  2719.     muluw    IMM((TASK_SIZE+1)+(PH_SIZE*2)+PAIR_SIZE+6),PVM1_REG
  2720.  
  2721.     addl    PVM1_REG,DTEMP1
  2722.     andw    IMM(-8),DTEMP1
  2723.  
  2724.     CMPL(    DTEMP1,HEAP_REG)
  2725.     subl    DTEMP1,HEAP_REG    /* allocate space for frames and check heap */
  2726.     BCSS(    do_gc)
  2727.     CMPL(    DISP(PSTATE_REG,SLOT(HEAP_LIM)),HEAP_REG) /* overflow */
  2728.     BCCS(    enough_space)
  2729. LBL(do_gc):
  2730.  
  2731.     moveq    IMM(0),PVM1_REG
  2732.     movl    DTEMP1,PDEC(SP)
  2733.     TRAP(heap_alloc2_trap,alloc,2,1)
  2734.     movl    PINC(SP),DTEMP1
  2735.  
  2736.     CMPL(    DTEMP1,HEAP_REG)
  2737.     subl    DTEMP1,HEAP_REG    /* allocate space for frames and check heap */
  2738.     BCSS(    stack_overflow)
  2739.     CMPL(    DISP(PSTATE_REG,SLOT(HEAP_LIM)),HEAP_REG) /* overflow */
  2740.     BCCS(    enough_space)
  2741. LBL(stack_overflow):
  2742.     addl    DTEMP1,HEAP_REG
  2743.  
  2744. /* continuation must be discarded... */
  2745.  
  2746.     movl    DISP(PSTATE_REG,SLOT(BOS_RET)),PVM0_REG
  2747.  
  2748.     movl    CONST(2),ATEMP1    /* jump to ##exception.stack-overflow proc */
  2749.     moveq    IMM(1),DTEMP1    /* passing 0 argument */
  2750.     jmp    IND(ATEMP1)
  2751.  
  2752. LBL(enough_space):
  2753.     addl    DTEMP1,HEAP_REG
  2754.  
  2755. /* At this point, we know that there is enough free space on the heap to */
  2756. /* copy the frames.                                                      */
  2757.  
  2758. /* Transfer a first task. */
  2759.  
  2760.     movl    NULL_REG,PVM2_REG    /* specify task list up to now */
  2761.  
  2762. #ifndef MESSAGE_PASSING_STEAL
  2763.     movl    FALSE_REG,DISP(PSTATE_REG,SLOT(STEAL_LOCKO))
  2764. LBL(lock_steal2):
  2765.     tstl    DISP(PSTATE_REG,SLOT(STEAL_LOCKV))
  2766.     BNES(    lock_steal2)
  2767.  
  2768. /* fix PARENT_RET if it is a lazy future return point */
  2769.  
  2770.     movl    DISP(PSTATE_REG,SLOT(PARENT_RET)),PVM0_REG
  2771.     tstw    DISP(PVM0_REG,-6)
  2772.     BPLS(    fixed)
  2773.  
  2774.     movl    DISP(PSTATE_REG,SLOT(LTQ_HEAD)),ATEMP1
  2775.     movl    DISP(ATEMP1,-SLOT(1)),ATEMP1
  2776. LBL(loop1):
  2777.     CMPL(    PDEC(ATEMP1),PVM0_REG)
  2778.     BNES(    loop1)
  2779.     movl    DISP(PSTATE_REG,SLOT(BOS_RET)),IND(ATEMP1)
  2780.  
  2781.     movl    CONST(3),PVM0_REG
  2782.     addw    IMM(16),PVM0_REG
  2783.     movl    PVM0_REG,DISP(PSTATE_REG,SLOT(PARENT_RET))
  2784.  
  2785. LBL(fixed):
  2786.  
  2787. #endif
  2788.  
  2789.     movl    DISP(PSTATE_REG,SLOT(LTQ_HEAD)),ATEMP1
  2790.     movl    DISP(ATEMP1,-SLOT(1)),PVM3_REG
  2791.     CMPL(    LTQ_TAIL_REG,ATEMP1)
  2792.     BEQS(    tasks_transferred)
  2793.  
  2794.     addql    IMM(4),ATEMP1    /* adjust LTQ_HEAD by one task */
  2795.  
  2796.     pea    PC_IND(ret)
  2797.     movl    CONST(0),ATEMP2
  2798.     jmp    IND(ATEMP2)
  2799.  
  2800. LBL(ret):
  2801.     movl    PVM2_REG,DISP(PSTATE_REG,SLOT(TEMP1))    /* save first task */
  2802.  
  2803. /* Transfer the rest. */
  2804.  
  2805. LBL(loop2):
  2806.     movl    DISP(PSTATE_REG,SLOT(LTQ_HEAD)),ATEMP1
  2807.     movl    DISP(ATEMP1,-SLOT(1)),PVM3_REG
  2808.     CMPL(    LTQ_TAIL_REG,ATEMP1)
  2809.     BEQS(    done)
  2810.  
  2811.     pea    PC_IND(loop2)
  2812.     movl    CONST(1),ATEMP2
  2813.     jmp    IND(ATEMP2)
  2814.  
  2815. LBL(done):
  2816.  
  2817. /* Put the tasks on the workq. */
  2818.  
  2819.     movl    FALSE_REG,DISP(PSTATE_REG,SLOT(WORKQ_LOCKO))
  2820. LBL(lock_workq):
  2821.     tstl    DISP(PSTATE_REG,SLOT(WORKQ_LOCKV))
  2822.     BNES(    lock_workq)
  2823.  
  2824.     movl    DISP(PSTATE_REG,SLOT(WORKQ_TAIL)),ATEMP1
  2825.     CMPL(    ATEMP1,NULL_REG)
  2826.     BNES(    non_empty_queue)
  2827.     movl    PVM2_REG,DISP(PSTATE_REG,SLOT(WORKQ_HEAD))
  2828.     BRAS(    fix_tail)
  2829. LBL(non_empty_queue):
  2830.     movl    PVM2_REG,PDEC(ATEMP1)
  2831. LBL(fix_tail):
  2832.     movl    DISP(PSTATE_REG,SLOT(TEMP1)),DISP(PSTATE_REG,SLOT(WORKQ_TAIL))
  2833.  
  2834.     clrl    DISP(PSTATE_REG,SLOT(WORKQ_LOCKO))
  2835.  
  2836. LBL(tasks_transferred):
  2837.  
  2838. #ifndef MESSAGE_PASSING_STEAL
  2839.     clrl    DISP(PSTATE_REG,SLOT(STEAL_LOCKO))
  2840. #endif
  2841.  
  2842.     rts
  2843.  
  2844. CONSTS(4)
  2845. PRIMITIVE("###_kernel.transfer-lazy-task-to-heap")
  2846. PRIMITIVE("###_kernel.transfer-lazy-task-chunk-to-heap")
  2847. PRIMITIVE("##exception.stack-overflow")
  2848. PRIMITIVE("###_kernel.task")
  2849. END
  2850.  
  2851. /*---------------------------------------------------------------------------*/
  2852.  
  2853. #undef LBL
  2854. #define LBL(x)MAKE_LBL(38,x)
  2855.  
  2856. BEGIN("###_kernel.transfer-stack-to-heap")
  2857.  
  2858. /* On entry:                                                       */
  2859. /*   top of stack = exit address                                   */
  2860. /*   next on stack = continuation's return address                 */
  2861.  
  2862. /* On exit:                                                        */
  2863. /*   top of stack = continuation's return address                  */
  2864. /*   PVM2_REG = continuation's first frame                         */
  2865. /*   PVM4_REG preserved                                            */
  2866. /*   PVM0_REG, PVM1_REG, PVM3_REG, DTEMP1, ATEMP1, ATEMP2 modified */
  2867.  
  2868. /* It is assumed that:                                                 */
  2869. /*   - no GC will be required (there is enough free space in the heap) */
  2870. /*   - there are no tasks on the stack                                 */
  2871.  
  2872.     movl    DISP(PSTATE_REG,SLOT(BOS_RET)),PVM3_REG
  2873.     lea    DISP(SP,SLOT(1)),ATEMP2
  2874.     movl    PINC(ATEMP2),PVM0_REG
  2875.     CMPL(    PVM0_REG,PVM3_REG)
  2876.     BNES(    non_empty_stack)
  2877.  
  2878.     movl    DISP(PSTATE_REG,SLOT(PARENT_RET)),DISP(SP,SLOT(1))
  2879.     movl    DISP(PSTATE_REG,SLOT(PARENT_FRAME)),PVM2_REG
  2880.  
  2881. #ifdef debug
  2882. /*****/    pea    PC_IND($entry)
  2883. /*****/    movl    PINC(SP),DISP(PSTATE_REG,SLOT(56))
  2884. /*****/    movl    IND(SP),DISP(PSTATE_REG,SLOT(57))
  2885. /*****/    movl    IMM(0),DISP(PSTATE_REG,SLOT(58))
  2886. #endif
  2887.  
  2888.     rts
  2889.  
  2890. LBL(non_empty_stack):
  2891.  
  2892. /* Chunk frames together. */
  2893.  
  2894.     lea    DISP(ATEMP2,SLOT(MAX_FRAME_CHUNK_SIZE)),ATEMP1
  2895.  
  2896.     moveq    IMM(0),PVM1_REG
  2897.     movw    DISP(PVM0_REG,-6),PVM1_REG    /* get fs */
  2898.     BGTS(    normal_ret_a1)
  2899. #ifdef debug
  2900. /*****/    BEQS(    dyn_env_ret_a1)
  2901. /*****/    jmp    3
  2902. /*****/LBL(dyn_env_ret_a1):
  2903. #endif
  2904.     movw    IMM(SLOT(DYN_ENV_FS)),PVM1_REG
  2905. LBL(normal_ret_a1):
  2906.     addl    ATEMP2,PVM1_REG
  2907.     BRAS(    try_to_add_next_frame1)
  2908.  
  2909. LBL(not_bottom_of_stack1):
  2910.     movl    PVM1_REG,ATEMP2
  2911.     moveq    IMM(0),PVM1_REG
  2912.     movw    DISP(PVM0_REG,-6),PVM1_REG    /* get fs */
  2913.     BGTS(    normal_ret_b1)
  2914. #ifdef debug
  2915. /*****/    BEQS(    dyn_env_ret_b1)
  2916. /*****/    jmp    5
  2917. /*****/LBL(dyn_env_ret_b1):
  2918. #endif
  2919.     movw    IMM(SLOT(DYN_ENV_FS)),PVM1_REG
  2920. LBL(normal_ret_b1):
  2921.     addl    ATEMP2,PVM1_REG
  2922.     CMPL(    ATEMP1,PVM1_REG)
  2923.     BHIS(    chunk_found1)
  2924. LBL(try_to_add_next_frame1):
  2925.     addw    DISP(PVM0_REG,-4),ATEMP2    /* add link */
  2926.     movl    IND(ATEMP2),PVM0_REG
  2927.     CMPL(    PVM0_REG,PVM3_REG)        /* bottom of stack? */
  2928.     BNES(    not_bottom_of_stack1)
  2929.     movl    DISP(PSTATE_REG,SLOT(PARENT_RET)),IND(ATEMP2)
  2930.     movl    PVM1_REG,ATEMP2
  2931.  
  2932. LBL(chunk_found1):  /* ATEMP2 = chunk's upper limit */
  2933.  
  2934. /* Now, compute size of frame object to hold chunk. */
  2935.  
  2936.     movl    ATEMP2,PVM1_REG
  2937.     lea    DISP(ATEMP1,-SLOT(MAX_FRAME_CHUNK_SIZE)),ATEMP2
  2938.     subl    ATEMP2,PVM1_REG
  2939.     addql    IMM(4),PVM1_REG
  2940.  
  2941. /* Allocate frame object. */
  2942.  
  2943.     movl    PVM1_REG,DTEMP1
  2944.     addw    IMM(11),DTEMP1
  2945.     andw    IMM(-8),DTEMP1
  2946.     subl    DTEMP1,HEAP_REG
  2947.     asll    IMM(8),PVM1_REG
  2948.     movb    IMM(SCM_subtype_FRAME*8),PVM1_REG
  2949.     movl    PVM1_REG,IND(HEAP_REG)
  2950.  
  2951. /* Remember where first frame object is. */
  2952.  
  2953.     movl    HEAP_REG,PVM2_REG
  2954.     addql    IMM(SCM_type_SUBTYPED),PVM2_REG
  2955.  
  2956. LBL(copy_stack):
  2957.  
  2958. /* Copy stack to frame object. */
  2959.  
  2960. /* PVM1_REG=frame_header, ATEMP2=start_of_chunk, HEAP_REG=frame_object */
  2961.  
  2962.     lsrl    IMM(8),PVM1_REG
  2963.     lsrl    IMM(2),PVM1_REG
  2964.     subql    IMM(2),PVM1_REG
  2965.  
  2966.     lea    DISP(HEAP_REG,SLOT(2)),ATEMP1
  2967. LBL(copy_loop):
  2968.     movl    PINC(ATEMP2),PINC(ATEMP1)
  2969.     DBRA(    PVM1_REG,copy_loop)
  2970.  
  2971.     CMPL(    PVM0_REG,PVM3_REG)        /* bottom of stack? */
  2972.     BNES(    next_chunks)
  2973.  
  2974.     movl    DISP(PSTATE_REG,SLOT(PARENT_FRAME)),DISP(HEAP_REG,SLOT(1))
  2975.     rts
  2976.  
  2977. LBL(next_chunks):
  2978.  
  2979. /* Process next chunk(s). */
  2980.  
  2981.     lea    DISP(ATEMP2,SLOT(MAX_FRAME_CHUNK_SIZE)),ATEMP1
  2982.  
  2983.     moveq    IMM(0),PVM1_REG
  2984.     movw    DISP(PVM0_REG,-6),PVM1_REG    /* get fs */
  2985.     BGTS(    normal_ret_a2)
  2986. #ifdef debug
  2987. /*****/    BEQS(    dyn_env_ret_a2)
  2988. /*****/    jmp    7
  2989. /*****/LBL(dyn_env_ret_a2):
  2990. #endif
  2991.     movw    IMM(SLOT(DYN_ENV_FS)),PVM1_REG
  2992. LBL(normal_ret_a2):
  2993.     addl    ATEMP2,PVM1_REG
  2994.     BRAS(    try_to_add_next_frame2)
  2995.  
  2996. LBL(not_bottom_of_stack2):
  2997.     movl    PVM1_REG,ATEMP2
  2998.     moveq    IMM(0),PVM1_REG
  2999.     movw    DISP(PVM0_REG,-6),PVM1_REG    /* get fs */
  3000.     BGTS(    normal_ret_b2)
  3001. #ifdef debug
  3002. /*****/    BEQS(    dyn_env_ret_b2)
  3003. /*****/    jmp    9
  3004. /*****/LBL(dyn_env_ret_b2):
  3005. #endif
  3006.     movw    IMM(SLOT(DYN_ENV_FS)),PVM1_REG
  3007. LBL(normal_ret_b2):
  3008.     addl    ATEMP2,PVM1_REG
  3009.     CMPL(    ATEMP1,PVM1_REG)
  3010.     BHIS(    chunk_found2)
  3011. LBL(try_to_add_next_frame2):
  3012.     addw    DISP(PVM0_REG,-4),ATEMP2    /* add link */
  3013.     movl    IND(ATEMP2),PVM0_REG
  3014.     CMPL(    PVM0_REG,PVM3_REG)        /* bottom of stack? */
  3015.     BNES(    not_bottom_of_stack2)
  3016.     movl    DISP(PSTATE_REG,SLOT(PARENT_RET)),IND(ATEMP2)
  3017.     movl    PVM1_REG,ATEMP2
  3018.  
  3019. LBL(chunk_found2):  /* ATEMP2 = chunk's upper limit */
  3020.  
  3021. /* Now, compute size of frame object to hold chunk. */
  3022.  
  3023.     movl    ATEMP2,PVM1_REG
  3024.     lea    DISP(ATEMP1,-SLOT(MAX_FRAME_CHUNK_SIZE)),ATEMP2
  3025.     subl    ATEMP2,PVM1_REG
  3026.     addql    IMM(4),PVM1_REG
  3027.  
  3028. /* Remember previous frame object */
  3029.  
  3030.     movl    HEAP_REG,ATEMP1
  3031.  
  3032. /* Allocate frame object. */
  3033.  
  3034.     movl    PVM1_REG,DTEMP1
  3035.     addw    IMM(11),DTEMP1
  3036.     andw    IMM(-8),DTEMP1
  3037.     subl    DTEMP1,HEAP_REG
  3038.     asll    IMM(8),PVM1_REG
  3039.     movb    IMM(SCM_subtype_FRAME*8),PVM1_REG
  3040.     movl    PVM1_REG,IND(HEAP_REG)
  3041.  
  3042. /* Link with previous frame object */
  3043.  
  3044.     addql    IMM(SCM_type_SUBTYPED),HEAP_REG
  3045.     movl    HEAP_REG,DISP(ATEMP1,SLOT(1))
  3046.     subql    IMM(SCM_type_SUBTYPED),HEAP_REG
  3047.  
  3048.     BRAW(    copy_stack)
  3049.  
  3050. CONSTS(0)
  3051. END
  3052.  
  3053. /*---------------------------------------------------------------------------*/
  3054.  
  3055. #undef LBL
  3056. #define LBL(x)MAKE_LBL(39,x)
  3057.  
  3058. BEGIN("###_kernel.flush-stack")
  3059.  
  3060.     movl    PVM0_REG,PDEC(SP)
  3061.  
  3062. /* Call ###_kernel.transfer-lazy-tasks-to-heap. */
  3063.  
  3064.     pea    PC_IND(ret1)
  3065.     movl    CONST(0),ATEMP1
  3066.     jmp    IND(ATEMP1)
  3067. RETURN(ret1,1,1):
  3068.  
  3069. /* Call ###_kernel.transfer-stack-to-heap. */
  3070.  
  3071. /* ###_kernel.transfer-lazy-tasks-to-heap has reserved enough */
  3072. /* space, so no GC check required.                            */
  3073.  
  3074.     pea    PC_IND(ret2)
  3075.     movl    CONST(1),ATEMP1
  3076.     jmp    IND(ATEMP1)
  3077. LBL(ret2):
  3078.  
  3079. /* Setup 'hidden' parent continuation. */
  3080.  
  3081.     movl    IND(SP),DISP(PSTATE_REG,SLOT(PARENT_RET))
  3082.     movl    PVM2_REG,DISP(PSTATE_REG,SLOT(PARENT_FRAME))
  3083.  
  3084. #ifdef debug
  3085. /*****/    pea    PC_IND($entry)
  3086. /*****/    movl    PINC(SP),DISP(PSTATE_REG,SLOT(56))
  3087. /*****/    movl    DISP(PSTATE_REG,SLOT(BOS_RET)),DISP(PSTATE_REG,SLOT(57))
  3088. /*****/    movl    IMM(0),DISP(PSTATE_REG,SLOT(58))
  3089. #endif
  3090.  
  3091. /* Return to parent */
  3092.  
  3093.     moveq    IMM(0),PVM1_REG
  3094.     movl    PVM1_REG,PVM2_REG
  3095.     movl    PVM1_REG,PVM3_REG
  3096.  
  3097.     movl    DISP(PSTATE_REG,SLOT(BOS_RET)),PVM0_REG
  3098.     jmp    IND(PVM0_REG)
  3099.  
  3100. CONSTS(2)
  3101. PRIMITIVE("###_kernel.transfer-lazy-tasks-to-heap")
  3102. PRIMITIVE("###_kernel.transfer-stack-to-heap")
  3103. END
  3104.  
  3105. /*---------------------------------------------------------------------------*/
  3106.  
  3107. #undef LBL
  3108. #define LBL(x)MAKE_LBL(40,x)
  3109.  
  3110. BEGIN("##call-with-current-continuation")
  3111.  
  3112.     BMIS(    passed_1arg)
  3113.  
  3114.     WRONG_NB_ARGS(wrong_nb_arg1_trap,1,$entry)
  3115.  
  3116. LBL(passed_1arg):
  3117.  
  3118.     movl    PVM1_REG,PVM4_REG
  3119.     movl    PVM0_REG,PDEC(SP)
  3120.  
  3121. /* Call ###_kernel.transfer-lazy-tasks-to-heap. */
  3122.  
  3123.     pea    PC_IND(ret1)
  3124.     movl    CONST(0),ATEMP1
  3125.     jmp    IND(ATEMP1)
  3126. RETURN(ret1,1,1):
  3127.  
  3128. /* Call ###_kernel.transfer-stack-to-heap. */
  3129.  
  3130. /* ###_kernel.transfer-lazy-tasks-to-heap has reserved enough */
  3131. /* space, so no GC check required.                            */
  3132.  
  3133.     pea    PC_IND(ret2)
  3134.     movl    CONST(1),ATEMP1
  3135.     jmp    IND(ATEMP1)
  3136. LBL(ret2):
  3137.  
  3138. /* Setup 'hidden' parent continuation. */
  3139.  
  3140.     movl    PINC(SP),PVM0_REG
  3141.     movl    PVM0_REG,DISP(PSTATE_REG,SLOT(PARENT_RET))
  3142.     movl    PVM2_REG,DISP(PSTATE_REG,SLOT(PARENT_FRAME))
  3143.  
  3144. #ifdef debug
  3145. /*****/    pea    PC_IND($entry)
  3146. /*****/    movl    PINC(SP),DISP(PSTATE_REG,SLOT(56))
  3147. /*****/    movl    DISP(PSTATE_REG,SLOT(BOS_RET)),DISP(PSTATE_REG,SLOT(57))
  3148. /*****/    movl    IMM(0),DISP(PSTATE_REG,SLOT(58))
  3149. #endif
  3150.  
  3151. /* Return to parent */
  3152.  
  3153.     movl    DISP(PSTATE_REG,SLOT(BOS_RET)),PDEC(SP)
  3154.  
  3155.     moveq    IMM(0),PVM1_REG
  3156.     movl    PVM1_REG,PVM3_REG
  3157.  
  3158. /* Allocate closure for 'first-class' continuation. */
  3159.  
  3160.     movl    DISP(PSTATE_REG,SLOT(CLOSURE_PTR)),ATEMP2
  3161.     moveq    IMM(32),DTEMP1
  3162.     subl    DTEMP1,ATEMP2
  3163.     CMPL(    DISP(PSTATE_REG,SLOT(CLOSURE_LIM)),ATEMP2)
  3164.     BCCS(    closure_allocated)
  3165.  
  3166.     moveq    IMM(0),PVM1_REG
  3167.     TRAP(closure_alloc_trap,closure_alloc,1,1)
  3168.  
  3169. LBL(closure_allocated):
  3170.     movl    ATEMP2,DISP(PSTATE_REG,SLOT(CLOSURE_PTR))
  3171.  
  3172. /* Init closure. */
  3173.  
  3174.     movw    IMM(0x8010),PINC(ATEMP2)
  3175.     movl    ATEMP2,PVM1_REG
  3176.     addql    IMM(2),ATEMP2
  3177.     lea    PC_IND(closure),ATEMP1
  3178.     movl    ATEMP1,PINC(ATEMP2)
  3179.     movl    PVM0_REG,PINC(ATEMP2)
  3180.     movl    PVM2_REG,PINC(ATEMP2)
  3181.     movl    DISP(PSTATE_REG,SLOT(CURRENT_DYN_ENV)),IND(ATEMP2)
  3182.  
  3183.     movl    PINC(SP),PVM0_REG
  3184.  
  3185.     movl    PVM4_REG,ATEMP1
  3186.     moveq    IMM(-1),DTEMP1
  3187.     jmp    IND(ATEMP1)
  3188.  
  3189. /* This code is executed when the 'first-class' continuation is restored. */
  3190.  
  3191. SUBPROC(closure):
  3192.     movl    PINC(SP),CLOSURE_REG
  3193.     subql    IMM(6),CLOSURE_REG
  3194.     tstw    DTEMP1
  3195.  
  3196.     BMIS(    closure_was_passed_1arg)
  3197.  
  3198.     WRONG_NB_ARGS(wrong_nb_arg1_closed_trap,1,closure)
  3199.  
  3200. LBL(closure_was_passed_1arg):
  3201.  
  3202. /* Call ###_kernel.transfer-lazy-tasks-to-heap. */
  3203.  
  3204.     CMPL(    DISP(PSTATE_REG,SLOT(LTQ_HEAD)),LTQ_TAIL_REG)
  3205.     BEQS(    tasks_transferred)
  3206.  
  3207.     movl    PVM0_REG,PDEC(SP)
  3208.     movl    PVM1_REG,PDEC(SP)
  3209.     pea    PC_IND(ret3)
  3210.     movl    CONST(0),ATEMP1
  3211.     jmp    IND(ATEMP1)
  3212. RETURN(ret3,2,1):
  3213.     movl    PINC(SP),PVM1_REG
  3214.     movl    PINC(SP),PVM0_REG
  3215.     moveq    IMM(0),PVM3_REG
  3216.  
  3217. LBL(tasks_transferred):
  3218.  
  3219. /* Setup 'hidden' parent continuation. */
  3220.  
  3221.     movl    CLOSURE_REG,ATEMP1
  3222.     movl    DISP(ATEMP1,6),DISP(PSTATE_REG,SLOT(PARENT_RET))
  3223.     movl    DISP(ATEMP1,10),DISP(PSTATE_REG,SLOT(PARENT_FRAME))
  3224.     movl    DISP(ATEMP1,14),DISP(PSTATE_REG,SLOT(CURRENT_DYN_ENV))
  3225.  
  3226. #ifdef debug
  3227. /*****/    pea    PC_IND($entry)
  3228. /*****/    movl    PINC(SP),DISP(PSTATE_REG,SLOT(56))
  3229. /*****/    movl    DISP(PSTATE_REG,SLOT(BOS_RET)),DISP(PSTATE_REG,SLOT(57))
  3230. /*****/    movl    IMM(0),DISP(PSTATE_REG,SLOT(58))
  3231. #endif
  3232.  
  3233. /* Restore parent continuation. */
  3234.  
  3235.     movl    DISP(PSTATE_REG,SLOT(BOS_RET)),ATEMP1
  3236.     jmp    IND(ATEMP1)
  3237.  
  3238. CONSTS(2)
  3239. PRIMITIVE("###_kernel.transfer-lazy-tasks-to-heap")
  3240. PRIMITIVE("###_kernel.transfer-stack-to-heap")
  3241. END
  3242.  
  3243. /*---------------------------------------------------------------------------*/
  3244.  
  3245. #undef LBL
  3246. #define LBL(x)MAKE_LBL(41,x)
  3247.  
  3248. BEGIN("##apply")
  3249.  
  3250.     BEQS(    passed_2args)
  3251.  
  3252.     WRONG_NB_ARGS(wrong_nb_arg1_trap,2,$entry)
  3253.  
  3254. LBL(passed_2args):
  3255.     movl    PVM1_REG,ATEMP1
  3256.     movl    PVM2_REG,PVM3_REG
  3257.  
  3258.     moveq    IMM(0),DTEMP1
  3259.     BRAS(    loop_entry)
  3260.  
  3261. /* copy values from list to the stack */
  3262.  
  3263. LBL(loop):
  3264.     movl    PVM3_REG,ATEMP2
  3265.     movl    IND(ATEMP2),PDEC(SP)    /* push car to the stack */
  3266.     movl    PDEC(ATEMP2),PVM3_REG    /* get cdr */
  3267.  
  3268.     addqw    IMM(1),DTEMP1
  3269.     CMPW(    IMM(MAX_NB_ARGS),DTEMP1)
  3270.     BGTS(    max_args_reached)
  3271.  
  3272. LBL(loop_entry):
  3273.     btst    PVM3_REG,PAIR_REG    /* pair? */
  3274.     BEQS(    loop)
  3275.  
  3276.     moveq    IMM(0),INTR_TIMER_REG    /* check interrupts as soon as possible */
  3277.  
  3278.     tstw    DTEMP1            /* how many arguments to pass? */
  3279.     BEQS(    pass_0arg)
  3280.     subqw    IMM(2),DTEMP1
  3281.     BMIS(    pass_1arg)
  3282.     BEQS(    pass_2args)
  3283.  
  3284.     movl    PINC(SP),PVM3_REG
  3285.     movl    PINC(SP),PVM2_REG
  3286.     movl    PINC(SP),PVM1_REG
  3287.     addqw    IMM(3),DTEMP1
  3288.     jmp    IND(ATEMP1)        /* jump to procedure (with >= 3 args) */
  3289.  
  3290. LBL(pass_0arg):
  3291.     moveq    IMM(1),DTEMP1
  3292.     jmp    IND(ATEMP1)        /* jump to procedure (with no arg) */
  3293.  
  3294. LBL(pass_1arg):
  3295.     movl    PINC(SP),PVM1_REG
  3296.     moveq    IMM(-1),DTEMP1
  3297.     jmp    IND(ATEMP1)        /* jump to procedure (with 1 arg) */
  3298.  
  3299. LBL(pass_2args):
  3300.     movl    PINC(SP),PVM2_REG
  3301.     movl    PINC(SP),PVM1_REG
  3302.     moveq    IMM(0),DTEMP1
  3303.     jmp    IND(ATEMP1)        /* jump to procedure (with 2 args) */
  3304.  
  3305. LBL(max_args_reached):
  3306.     aslw    IMM(2),DTEMP1
  3307.     addw    DTEMP1,SP        /* restore original SP */
  3308.  
  3309.     movl    CONST(0),ATEMP1        /* jump to ##exception.apply-arg-limit */
  3310.     moveq    IMM(0),DTEMP1        /* passing 2 arguments */
  3311.     jmp    IND(ATEMP1)
  3312.  
  3313. CONSTS(1)
  3314. PRIMITIVE("##exception.apply-arg-limit")
  3315. END
  3316.  
  3317. /*---------------------------------------------------------------------------*/
  3318.  
  3319. #undef LBL
  3320. #define LBL(x)MAKE_LBL(42,x)
  3321.  
  3322. BEGIN("##global-var")
  3323.  
  3324.     BMIS(    passed_1arg)
  3325.  
  3326.     WRONG_NB_ARGS(wrong_nb_arg1_trap,1,$entry)
  3327.  
  3328. LBL(passed_1arg):
  3329.     movl    PVM1_REG,ATEMP2
  3330.     movl    DISP(ATEMP2,SLOT(SYMBOL_GLOBAL)+4-SCM_type_SUBTYPED),PVM1_REG
  3331.  
  3332.     CMPL(    PVM1_REG,FALSE_REG)
  3333.     BEQS(    alloc_glob)
  3334.  
  3335.     jmp    IND(PVM0_REG)
  3336.  
  3337. LBL(alloc_glob):
  3338.     movl    DISP(TABLE_REG,GLOB_OFFS(GLOBAL_VAR_COUNT)),ATEMP1
  3339.     movl    ATEMP1,PVM1_REG
  3340.     addql    IMM(8),ATEMP1
  3341.     CMPL(    IMM(MAX_NB_GLOBALS*8),ATEMP1)
  3342.     BLES(    ok)
  3343.  
  3344.     movl    FALSE_REG,PVM1_REG
  3345.     jmp    IND(PVM0_REG)
  3346.  
  3347. LBL(ok):
  3348.     movl    ATEMP1,DISP(TABLE_REG,GLOB_OFFS(GLOBAL_VAR_COUNT))
  3349.     movl    PVM1_REG,DISP(ATEMP2,SLOT(SYMBOL_GLOBAL)+4-SCM_type_SUBTYPED)
  3350.  
  3351.     jmp    IND(PVM0_REG)
  3352.  
  3353. CONSTS(0)
  3354. END
  3355.  
  3356. /*---------------------------------------------------------------------------*/
  3357.  
  3358. #undef LBL
  3359. #define LBL(x)MAKE_LBL(43,x)
  3360.  
  3361. BEGIN("##global-var-ref")
  3362.  
  3363.     BMIS(    passed_1arg)
  3364.  
  3365.     WRONG_NB_ARGS(wrong_nb_arg1_trap,1,$entry)
  3366.  
  3367. LBL(passed_1arg):
  3368.     movl    PVM1_REG,ATEMP1
  3369.     addl    TABLE_REG,ATEMP1
  3370.     subl    IMM((NB_TRAPS*8-0x8000)+(MAX_NB_GLOBALS*10)),ATEMP1
  3371.  
  3372.     movl    IND(ATEMP1),PVM1_REG
  3373.     jmp    IND(PVM0_REG)
  3374.  
  3375. CONSTS(0)
  3376. END
  3377.  
  3378. /*---------------------------------------------------------------------------*/
  3379.  
  3380. #undef LBL
  3381. #define LBL(x)MAKE_LBL(44,x)
  3382.  
  3383. BEGIN("##global-var-set!")
  3384.  
  3385.     BEQS(    passed_2args)
  3386.  
  3387.     WRONG_NB_ARGS(wrong_nb_arg1_trap,2,$entry)
  3388.  
  3389. LBL(passed_2args):
  3390.     movl    PVM1_REG,DTEMP1
  3391.     asrl    IMM(2),DTEMP1
  3392.     addl    TABLE_REG,DTEMP1
  3393.     subl    IMM(NB_TRAPS*8-0x8000),DTEMP1
  3394.     subl    IMM(MAX_NB_GLOBALS*2),DTEMP1
  3395.  
  3396.     movl    PVM1_REG,ATEMP1
  3397.     addl    TABLE_REG,ATEMP1
  3398.     subl    IMM(NB_TRAPS*8-0x8000),ATEMP1
  3399.     subl    IMM(MAX_NB_GLOBALS*10),ATEMP1
  3400.  
  3401.     movl    PVM2_REG,PINC(ATEMP1)
  3402.     movl    DTEMP1,IND(ATEMP1)
  3403.  
  3404.     jmp    IND(PVM0_REG)
  3405.  
  3406. CONSTS(0)
  3407. END
  3408.  
  3409. /*---------------------------------------------------------------------------*/
  3410.  
  3411. #undef LBL
  3412. #define LBL(x)MAKE_LBL(45,x)
  3413.  
  3414. BEGIN("##make-vector")
  3415.  
  3416.     BEQS(    passed_2args)
  3417.  
  3418.     WRONG_NB_ARGS(wrong_nb_arg1_trap,2,$entry)
  3419.  
  3420. LBL(passed_2args):
  3421.     movl    PVM1_REG,DTEMP1
  3422.     asrl    IMM(1),DTEMP1
  3423.     addl    IMM(11),DTEMP1
  3424.     andw    IMM(-8),DTEMP1    /* DTEMP1 = total bytes needed for vector */
  3425.  
  3426.     CMPL(    DTEMP1,HEAP_REG)
  3427.     subl    DTEMP1,HEAP_REG    /* allocate space for vector and check heap overflow */
  3428.     BCSS(    gc)
  3429.     CMPL(    DISP(PSTATE_REG,SLOT(HEAP_LIM)),HEAP_REG)
  3430.     BCCS(    ok)
  3431. LBL(gc):
  3432.     movl    PVM0_REG,PDEC(SP)
  3433.     TRAP(heap_alloc2_trap,alloc1,1,1)
  3434.     movl    PINC(SP),PVM0_REG
  3435.  
  3436. LBL(ok):
  3437.     movl    PVM1_REG,DTEMP1
  3438.     asll    IMM(7),DTEMP1
  3439.     movb    IMM(SCM_subtype_VECTOR*8),DTEMP1
  3440.     movl    DTEMP1,IND(HEAP_REG)
  3441.  
  3442. /* init vector: */
  3443.  
  3444.     movl    PVM1_REG,DTEMP1
  3445.     asrl    IMM(1),DTEMP1
  3446.     lea    DISP(HEAP_REG,4),ATEMP1
  3447. LBL(loop):
  3448.     movl    PVM2_REG,PINC(ATEMP1)
  3449.     subql    IMM(4),DTEMP1
  3450.     BGTS(    loop)
  3451.  
  3452.     movl    HEAP_REG,PVM1_REG
  3453.     addql    IMM(SCM_type_SUBTYPED),PVM1_REG
  3454.  
  3455.     jmp    IND(PVM0_REG)        /* return to caller */
  3456.  
  3457. CONSTS(0)
  3458. END
  3459.  
  3460. /*---------------------------------------------------------------------------*/
  3461.  
  3462. #undef LBL
  3463. #define LBL(x)MAKE_LBL(46,x)
  3464.  
  3465. BEGIN("##make-string")
  3466.  
  3467.     BEQS(    passed_2args)
  3468.  
  3469.     WRONG_NB_ARGS(wrong_nb_arg1_trap,2,$entry)
  3470.  
  3471. LBL(passed_2args):
  3472.     movl    PVM1_REG,DTEMP1
  3473.     asrl    IMM(3),DTEMP1
  3474.     addl    IMM(11),DTEMP1
  3475.     andw    IMM(-8),DTEMP1    /* DTEMP1 = total bytes needed for string */
  3476.  
  3477.     CMPL(    DTEMP1,HEAP_REG)
  3478.     subl    DTEMP1,HEAP_REG    /* allocate space for string and check heap overflow */
  3479.     BCSS(    gc)
  3480.     CMPL(    DISP(PSTATE_REG,SLOT(HEAP_LIM)),HEAP_REG)
  3481.     BCCS(    ok)
  3482. LBL(gc):
  3483.     movl    PVM0_REG,PDEC(SP)
  3484.     TRAP(heap_alloc2_trap,alloc1,1,1)
  3485.     movl    PINC(SP),PVM0_REG
  3486.  
  3487. LBL(ok):
  3488.     movl    PVM1_REG,DTEMP1
  3489.     asll    IMM(5),DTEMP1
  3490.     movb    IMM(SCM_subtype_STRING*8),DTEMP1
  3491.     movl    DTEMP1,IND(HEAP_REG)
  3492.  
  3493. /* init string: */
  3494.  
  3495.     movl    PVM2_REG,DTEMP1
  3496.     asrw    IMM(3),DTEMP1
  3497.     andw    IMM(0xff),DTEMP1
  3498.     movw    DTEMP1,ATEMP2
  3499.     aslw    IMM(8),DTEMP1
  3500.     addw    ATEMP2,DTEMP1
  3501.     movw    DTEMP1,ATEMP2
  3502.     swap    DTEMP1
  3503.     movw    ATEMP2,DTEMP1
  3504.     movl    DTEMP1,ATEMP2        /* ATEMP2 = initial value of chars */
  3505.  
  3506.     movl    PVM1_REG,DTEMP1
  3507.     asrl    IMM(3),DTEMP1
  3508.     lea    DISP(HEAP_REG,4),ATEMP1
  3509. LBL(loop):
  3510.     movl    ATEMP2,PINC(ATEMP1)
  3511.     subql    IMM(4),DTEMP1
  3512.     BGTS(    loop)
  3513.  
  3514.     movl    HEAP_REG,PVM1_REG
  3515.     addql    IMM(SCM_type_SUBTYPED),PVM1_REG
  3516.  
  3517.     jmp    IND(PVM0_REG)        /* return to caller */
  3518.  
  3519. CONSTS(0)
  3520. END
  3521.  
  3522. /*---------------------------------------------------------------------------*/
  3523.  
  3524. #undef LBL
  3525. #define LBL(x)MAKE_LBL(47,x)
  3526.  
  3527. BEGIN("##make-vector16")
  3528.  
  3529.     BEQS(    passed_2args)
  3530.  
  3531.     WRONG_NB_ARGS(wrong_nb_arg1_trap,2,$entry)
  3532.  
  3533. LBL(passed_2args):
  3534.     movl    PVM1_REG,DTEMP1
  3535.     asrl    IMM(2),DTEMP1
  3536.     addl    IMM(11),DTEMP1
  3537.     andw    IMM(-8),DTEMP1    /* DTEMP1 = total bytes needed for vector */
  3538.  
  3539.     CMPL(    DTEMP1,HEAP_REG)
  3540.     subl    DTEMP1,HEAP_REG    /* allocate space for vector and check heap overflow */
  3541.     BCSS(    gc)
  3542.     CMPL(    DISP(PSTATE_REG,SLOT(HEAP_LIM)),HEAP_REG)
  3543.     BCCS(    ok)
  3544. LBL(gc):
  3545.     movl    PVM0_REG,PDEC(SP)
  3546.     TRAP(heap_alloc2_trap,alloc1,1,1)
  3547.     movl    PINC(SP),PVM0_REG
  3548.  
  3549. LBL(ok):
  3550.     movl    PVM1_REG,DTEMP1
  3551.     asll    IMM(6),DTEMP1
  3552.     movb    IMM(SCM_subtype_STRING*8),DTEMP1
  3553.     movl    DTEMP1,IND(HEAP_REG)
  3554.  
  3555. /* init vector: */
  3556.  
  3557.     movl    PVM2_REG,DTEMP1
  3558.     asrl    IMM(3),DTEMP1
  3559.     movw    DTEMP1,ATEMP2
  3560.     swap    DTEMP1
  3561.     movw    ATEMP2,DTEMP1
  3562.     movl    DTEMP1,ATEMP2        /* ATEMP2 = initial value of words */
  3563.  
  3564.     movl    PVM1_REG,DTEMP1
  3565.     asrl    IMM(2),DTEMP1
  3566.     lea    DISP(HEAP_REG,4),ATEMP1
  3567. LBL(loop):
  3568.     movl    ATEMP2,PINC(ATEMP1)
  3569.     subql    IMM(4),DTEMP1
  3570.     BGTS(    loop)
  3571.  
  3572.     movl    HEAP_REG,PVM1_REG
  3573.     addql    IMM(SCM_type_SUBTYPED),PVM1_REG
  3574.  
  3575.     jmp    IND(PVM0_REG)        /* return to caller */
  3576.  
  3577. CONSTS(0)
  3578. END
  3579.  
  3580. /*---------------------------------------------------------------------------*/
  3581.  
  3582. #undef LBL
  3583. #define LBL(x)MAKE_LBL(48,x)
  3584.  
  3585. BEGIN("##dynamic-env-bind")
  3586.  
  3587.     BEQS(    passed_2args)
  3588.  
  3589.     WRONG_NB_ARGS(wrong_nb_arg1_trap,2,$entry)
  3590.  
  3591. LBL(passed_2args):
  3592.  
  3593. /* save current dynamic environment */
  3594.  
  3595.     movl    PVM0_REG,PDEC(SP)
  3596.     movl    DISP(PSTATE_REG,SLOT(CURRENT_DYN_ENV)),PDEC(SP)
  3597.  
  3598. /* set new dynamic environment */
  3599.  
  3600.     movl    PVM1_REG,DISP(PSTATE_REG,SLOT(CURRENT_DYN_ENV))
  3601.  
  3602. /* push dynamic environment marker (only if none other pushed for this future) */
  3603.  
  3604.     movl    DISP(PSTATE_REG,SLOT(DEQ_TAIL)),ATEMP2
  3605.     movl    IND(ATEMP2),PVM0_REG
  3606.     movl    DISP(LTQ_TAIL_REG,-SLOT(1)),ATEMP1
  3607.     CMPL(    ATEMP1,PVM0_REG)
  3608.     BCSS(    pushed)
  3609.     movl    SP,PDEC(ATEMP2)
  3610.     movl    ATEMP2,DISP(PSTATE_REG,SLOT(DEQ_TAIL))
  3611. LBL(pushed):
  3612.  
  3613.     lea    PC_IND(ret),PVM0_REG
  3614.     movl    PVM2_REG,ATEMP1
  3615.     moveq    IMM(1),DTEMP1
  3616.     jmp    IND(ATEMP1)
  3617.  
  3618. RETURN(ret,DYN_ENV_FS-DYN_ENV_FS,1-DYN_ENV_FS):
  3619. /* A fs of 0 is a special return point marker.  Here it indicates a return */
  3620. /* point for dyn env frames.  The frame size is really 2 (DYN_ENV_FS). */
  3621.  
  3622. /* pop dynamic environment marker */
  3623.  
  3624.     movl    DISP(PSTATE_REG,SLOT(DEQ_TAIL)),ATEMP2
  3625.     movl    PINC(ATEMP2),ATEMP1
  3626.     CMPL(    ATEMP1,SP)
  3627.     BNES(    popped)
  3628.     movl    ATEMP2,DISP(PSTATE_REG,SLOT(DEQ_TAIL))
  3629. LBL(popped):
  3630.  
  3631. /* restore current dynamic environment */
  3632.  
  3633.     movl    PINC(SP),DISP(PSTATE_REG,SLOT(CURRENT_DYN_ENV))
  3634.     rts
  3635.  
  3636. CONSTS(0)
  3637. END
  3638.  
  3639. /*---------------------------------------------------------------------------*/
  3640.  
  3641. #undef LBL
  3642. #define LBL(x)MAKE_LBL(49,x)
  3643.  
  3644. BEGIN("##dynamic-env-ref")
  3645.  
  3646.     CMPW(    IMM(1),DTEMP1)
  3647.     BEQS(    passed_0arg)
  3648.  
  3649.     WRONG_NB_ARGS(wrong_nb_arg1_trap,0,$entry)
  3650.  
  3651. LBL(passed_0arg):
  3652.     movl    DISP(PSTATE_REG,SLOT(CURRENT_DYN_ENV)),PVM1_REG
  3653.     jmp    IND(PVM0_REG)
  3654.  
  3655. CONSTS(0)
  3656. END
  3657.  
  3658. /*---------------------------------------------------------------------------*/
  3659.  
  3660. #undef LBL
  3661. #define LBL(x)MAKE_LBL(50,x)
  3662.  
  3663. BEGIN("##atomic-car")
  3664.  
  3665.     BMIS(    passed_1arg)
  3666.  
  3667.     WRONG_NB_ARGS(wrong_nb_arg1_trap,1,$entry)
  3668.  
  3669. LBL(passed_1arg):
  3670.     andw    IMM(-8),PVM1_REG
  3671.     movl    PVM1_REG,ATEMP2
  3672.  
  3673.     moveq    IMM(-1),DTEMP1
  3674. LBL(loop):
  3675.     movl    DISP(ATEMP2,4),PVM1_REG
  3676.     CMPL(    PVM1_REG,DTEMP1)
  3677.     BEQS(    loop)
  3678.  
  3679.     jmp    IND(PVM0_REG)
  3680.  
  3681. CONSTS(0)
  3682. END
  3683.  
  3684. /*---------------------------------------------------------------------------*/
  3685.  
  3686. #undef LBL
  3687. #define LBL(x)MAKE_LBL(51,x)
  3688.  
  3689. BEGIN("##atomic-set-car!")
  3690.  
  3691.     BEQS(    passed_2args)
  3692.  
  3693.     WRONG_NB_ARGS(wrong_nb_arg1_trap,2,$entry)
  3694.  
  3695. LBL(passed_2args):
  3696.     movl    PVM0_REG,PVM4_REG
  3697.     movl    PVM1_REG,DTEMP1
  3698.     andw    IMM(-8),DTEMP1
  3699.     addql    IMM(4),DTEMP1
  3700.     movl    DTEMP1,ATEMP2
  3701.  
  3702.     LOCK_ATEMP2(lock)
  3703.  
  3704.     movl    PVM2_REG,IND(ATEMP2)
  3705.     movl    DTEMP1,PVM1_REG
  3706.     movl    PVM4_REG,PVM0_REG
  3707.     jmp    IND(PVM0_REG)
  3708.  
  3709. CONSTS(0)
  3710. END
  3711.  
  3712. /*---------------------------------------------------------------------------*/
  3713.  
  3714. #undef LBL
  3715. #define LBL(x)MAKE_LBL(52,x)
  3716.  
  3717. BEGIN("##atomic-cdr")
  3718.  
  3719.     BMIS(    passed_1arg)
  3720.  
  3721.     WRONG_NB_ARGS(wrong_nb_arg1_trap,1,$entry)
  3722.  
  3723. LBL(passed_1arg):
  3724.     andw    IMM(-8),PVM1_REG
  3725.     movl    PVM1_REG,ATEMP2
  3726.  
  3727.     moveq    IMM(-1),DTEMP1
  3728. LBL(loop):
  3729.     movl    IND(ATEMP2),PVM1_REG
  3730.     CMPL(    PVM1_REG,DTEMP1)
  3731.     BEQS(    loop)
  3732.  
  3733.     jmp    IND(PVM0_REG)
  3734.  
  3735. CONSTS(0)
  3736. END
  3737.  
  3738. /*---------------------------------------------------------------------------*/
  3739.  
  3740. #undef LBL
  3741. #define LBL(x)MAKE_LBL(53,x)
  3742.  
  3743. BEGIN("##atomic-set-cdr!")
  3744.  
  3745.     BEQS(    passed_2args)
  3746.  
  3747.     WRONG_NB_ARGS(wrong_nb_arg1_trap,2,$entry)
  3748.  
  3749. LBL(passed_2args):
  3750.     movl    PVM0_REG,PVM4_REG
  3751.     movl    PVM1_REG,DTEMP1
  3752.     andw    IMM(-8),DTEMP1
  3753.     movl    DTEMP1,ATEMP2
  3754.  
  3755.     LOCK_ATEMP2(lock)
  3756.  
  3757.     movl    PVM2_REG,IND(ATEMP2)
  3758.     movl    DTEMP1,PVM1_REG
  3759.     movl    PVM4_REG,PVM0_REG
  3760.     jmp    IND(PVM0_REG)
  3761.  
  3762. CONSTS(0)
  3763. END
  3764.  
  3765. /*---------------------------------------------------------------------------*/
  3766.  
  3767. #undef LBL
  3768. #define LBL(x)MAKE_LBL(54,x)
  3769.  
  3770. BEGIN("##atomic-set-car-if-eq?!")
  3771.  
  3772.     CMPW(    IMM(4),DTEMP1)
  3773.     BEQS(    passed_3args)
  3774.  
  3775.     WRONG_NB_ARGS(wrong_nb_arg1_trap,3,$entry)
  3776.  
  3777. LBL(passed_3args):
  3778.     movl    PVM0_REG,PVM4_REG
  3779.     movl    PVM1_REG,DTEMP1
  3780.     andw    IMM(-8),DTEMP1
  3781.     addql    IMM(4),DTEMP1
  3782.     movl    DTEMP1,ATEMP2
  3783.  
  3784.     LOCK_ATEMP2(lock)
  3785.  
  3786.     CMPL(    DTEMP1,PVM3_REG)
  3787.     BNES(    not_eq)
  3788.  
  3789.     movl    PVM2_REG,IND(ATEMP2)
  3790.     movl    IMM(SCM_true),PVM1_REG
  3791.     movl    PVM4_REG,PVM0_REG
  3792.     jmp    IND(PVM0_REG)
  3793.  
  3794. LBL(not_eq):
  3795.     movl    DTEMP1,IND(ATEMP2)
  3796.     movl    FALSE_REG,PVM1_REG
  3797.     movl    PVM4_REG,PVM0_REG
  3798.     jmp    IND(PVM0_REG)
  3799.  
  3800. CONSTS(0)
  3801. END
  3802.  
  3803. /*---------------------------------------------------------------------------*/
  3804.  
  3805. #undef LBL
  3806. #define LBL(x)MAKE_LBL(55,x)
  3807.  
  3808. BEGIN("##atomic-set-cdr-if-eq?!")
  3809.  
  3810.     CMPW(    IMM(4),DTEMP1)
  3811.     BEQS(    passed_3args)
  3812.  
  3813.     WRONG_NB_ARGS(wrong_nb_arg1_trap,3,$entry)
  3814.  
  3815. LBL(passed_3args):
  3816.     movl    PVM0_REG,PVM4_REG
  3817.     movl    PVM1_REG,DTEMP1
  3818.     andw    IMM(-8),DTEMP1
  3819.     movl    DTEMP1,ATEMP2
  3820.  
  3821.     LOCK_ATEMP2(lock)
  3822.  
  3823.     CMPL(    DTEMP1,PVM3_REG)
  3824.     BNES(    not_eq)
  3825.  
  3826.     movl    PVM2_REG,IND(ATEMP2)
  3827.     movl    IMM(SCM_true),PVM1_REG
  3828.     movl    PVM4_REG,PVM0_REG
  3829.     jmp    IND(PVM0_REG)
  3830.  
  3831. LBL(not_eq):
  3832.     movl    DTEMP1,IND(ATEMP2)
  3833.     movl    FALSE_REG,PVM1_REG
  3834.     movl    PVM4_REG,PVM0_REG
  3835.     jmp    IND(PVM0_REG)
  3836.  
  3837. CONSTS(0)
  3838. END
  3839.  
  3840. /*---------------------------------------------------------------------------*/
  3841.  
  3842. #undef LBL
  3843. #define LBL(x)MAKE_LBL(550,x)
  3844.  
  3845. BEGIN("##make-queue")
  3846.  
  3847.     CMPW(    IMM(1),DTEMP1)
  3848.     BEQS(    passed_0arg)
  3849.  
  3850.     WRONG_NB_ARGS(wrong_nb_arg1_trap,0,$entry)
  3851.  
  3852. LBL(passed_0arg):
  3853.  
  3854.     subql    IMM(4),HEAP_REG
  3855.     movl    NULL_REG,PDEC(HEAP_REG)
  3856.     movl    NULL_REG,PDEC(HEAP_REG)
  3857.     movl    IMM(QUEUE_SIZE*0x400+(SCM_subtype_QUEUE*8)),PDEC(HEAP_REG)
  3858.     lea    DISP(HEAP_REG,SCM_type_SUBTYPED),ATEMP1
  3859.     movl    ATEMP1,PVM1_REG
  3860.  
  3861. /* check heap overflow */
  3862.  
  3863.     CMPL(    DISP(PSTATE_REG,SLOT(HEAP_LIM)),HEAP_REG)
  3864.     BCCS(    ok)
  3865.     movl    PVM0_REG,PDEC(SP)
  3866.     TRAP(heap_alloc1_trap,alloc1,1,1)
  3867.     movl    PINC(SP),PVM0_REG
  3868. LBL(ok):
  3869.  
  3870.     jmp    IND(PVM0_REG)
  3871.  
  3872. CONSTS(0)
  3873. END
  3874.  
  3875. /*---------------------------------------------------------------------------*/
  3876.  
  3877. #undef LBL
  3878. #define LBL(x)MAKE_LBL(551,x)
  3879.  
  3880. BEGIN("##queue-peek-list")
  3881.  
  3882.     BMIS(    passed_1arg)
  3883.  
  3884.     WRONG_NB_ARGS(wrong_nb_arg1_trap,1,$entry)
  3885.  
  3886. LBL(passed_1arg):
  3887.  
  3888.     movl    PVM1_REG,ATEMP2
  3889.     movl    DISP(ATEMP2,SLOT(QUEUE_HEAD)+4-SCM_type_SUBTYPED),PVM1_REG
  3890.     jmp    IND(PVM0_REG)
  3891.  
  3892. CONSTS(0)
  3893. END
  3894.  
  3895. /*---------------------------------------------------------------------------*/
  3896.  
  3897. #undef LBL
  3898. #define LBL(x)MAKE_LBL(552,x)
  3899.  
  3900. BEGIN("##queue-get-list!")
  3901.  
  3902.     BMIS(    passed_1arg)
  3903.  
  3904.     WRONG_NB_ARGS(wrong_nb_arg1_trap,1,$entry)
  3905.  
  3906. LBL(passed_1arg):
  3907.  
  3908.     movl    PVM1_REG,ATEMP2
  3909.     lea    DISP(ATEMP2,SLOT(QUEUE_TAIL)+4-SCM_type_SUBTYPED),ATEMP2
  3910.  
  3911.     movl    PVM0_REG,PVM3_REG
  3912.     LOCK_ATEMP2(lock)
  3913.     movl    PVM3_REG,PVM0_REG
  3914.  
  3915.     CMPL(    DTEMP1,NULL_REG)
  3916.     BEQS(    empty)
  3917.  
  3918.     movl    DISP(ATEMP2,SLOT(QUEUE_HEAD-QUEUE_TAIL)),PVM1_REG
  3919.     movl    NULL_REG,DISP(ATEMP2,SLOT(QUEUE_HEAD-QUEUE_TAIL))
  3920.     movl    NULL_REG,IND(ATEMP2)
  3921.     jmp    IND(PVM0_REG)
  3922.  
  3923. LBL(empty):
  3924.     movl    NULL_REG,PVM1_REG
  3925.     movl    NULL_REG,IND(ATEMP2)
  3926.     jmp    IND(PVM0_REG)
  3927.  
  3928. CONSTS(0)
  3929. END
  3930.  
  3931. /*---------------------------------------------------------------------------*/
  3932.  
  3933. #undef LBL
  3934. #define LBL(x)MAKE_LBL(553,x)
  3935.  
  3936. BEGIN("##queue-get!")
  3937.  
  3938.     BMIS(    passed_1arg)
  3939.  
  3940.     WRONG_NB_ARGS(wrong_nb_arg1_trap,1,$entry)
  3941.  
  3942. LBL(passed_1arg):
  3943.  
  3944.     movl    PVM1_REG,ATEMP2
  3945.     lea    DISP(ATEMP2,SLOT(QUEUE_TAIL)+4-SCM_type_SUBTYPED),ATEMP2
  3946.  
  3947.     movl    PVM0_REG,PVM3_REG
  3948.     LOCK_ATEMP2(lock)
  3949.     movl    PVM3_REG,PVM0_REG
  3950.  
  3951.     CMPL(    DTEMP1,NULL_REG)
  3952.     BEQS(    empty1)
  3953.  
  3954.     movl    DISP(ATEMP2,SLOT(QUEUE_HEAD-QUEUE_TAIL)),PVM1_REG
  3955.     movl    PVM1_REG,ATEMP1
  3956.     movl    PDEC(ATEMP1),PVM4_REG
  3957.     movl    NULL_REG,IND(ATEMP1)
  3958.     movl    PVM4_REG,DISP(ATEMP2,SLOT(QUEUE_HEAD-QUEUE_TAIL))
  3959.     CMPL(    PVM4_REG,NULL_REG)
  3960.     BEQS(    empty2)
  3961.     movl    DTEMP1,IND(ATEMP2)
  3962.     jmp    IND(PVM0_REG)
  3963.  
  3964. LBL(empty1):
  3965.     movl    FALSE_REG,PVM1_REG
  3966. LBL(empty2):
  3967.     movl    NULL_REG,IND(ATEMP2)
  3968.     jmp    IND(PVM0_REG)
  3969.  
  3970. CONSTS(0)
  3971. END
  3972.  
  3973. /*---------------------------------------------------------------------------*/
  3974.  
  3975. #undef LBL
  3976. #define LBL(x)MAKE_LBL(554,x)
  3977.  
  3978. BEGIN("##queue-put!")
  3979.  
  3980.     BEQS(    passed_2args)
  3981.  
  3982.     WRONG_NB_ARGS(wrong_nb_arg1_trap,2,$entry)
  3983.  
  3984. LBL(passed_2args):
  3985.  
  3986.     movl    PVM2_REG,PDEC(HEAP_REG)
  3987.     movl    HEAP_REG,PVM2_REG
  3988.     movl    NULL_REG,PDEC(HEAP_REG)
  3989.  
  3990.     movl    PVM1_REG,ATEMP2
  3991.     lea    DISP(ATEMP2,SLOT(QUEUE_TAIL)+4-SCM_type_SUBTYPED),ATEMP2
  3992.  
  3993.     movl    PVM0_REG,PVM3_REG
  3994.     movl    PVM1_REG,PVM4_REG
  3995.     LOCK_ATEMP2(lock)
  3996.     movl    PVM4_REG,PVM1_REG
  3997.     movl    PVM3_REG,PVM0_REG
  3998.  
  3999.     CMPL(    DTEMP1,NULL_REG)
  4000.     BEQS(    empty)
  4001.  
  4002.     movl    DTEMP1,ATEMP1
  4003.     movl    PVM2_REG,PDEC(ATEMP1)
  4004.     BRAS(    unlock)
  4005.  
  4006. LBL(empty):
  4007.     movl    PVM2_REG,DISP(ATEMP2,SLOT(QUEUE_HEAD-QUEUE_TAIL))
  4008.  
  4009. LBL(unlock):
  4010.     movl    PVM2_REG,IND(ATEMP2)
  4011.  
  4012. /* check heap overflow */
  4013.  
  4014.     CMPL(    DISP(PSTATE_REG,SLOT(HEAP_LIM)),HEAP_REG)
  4015.     BCCS(    ok)
  4016.     movl    PVM0_REG,PDEC(SP)
  4017.     TRAP(heap_alloc1_trap,alloc1,1,1)
  4018.     movl    PINC(SP),PVM0_REG
  4019. LBL(ok):
  4020.  
  4021.     jmp    IND(PVM0_REG)
  4022.  
  4023. CONSTS(0)
  4024. END
  4025.  
  4026. /*---------------------------------------------------------------------------*/
  4027.  
  4028. #undef LBL
  4029. #define LBL(x)MAKE_LBL(56,x)
  4030.  
  4031. BEGIN("##make-semaphore")
  4032.  
  4033.     CMPW(    IMM(1),DTEMP1)
  4034.     BEQS(    passed_0arg)
  4035.  
  4036.     WRONG_NB_ARGS(wrong_nb_arg1_trap,0,$entry)
  4037.  
  4038. LBL(passed_0arg):
  4039.  
  4040.     movl    IMM(1*8),PDEC(HEAP_REG)
  4041.     movl    NULL_REG,PDEC(HEAP_REG)
  4042.     movl    NULL_REG,PDEC(HEAP_REG)
  4043.     movl    IMM(SEMAPHORE_SIZE*0x400+(SCM_subtype_SEMAPHORE*8)),PDEC(HEAP_REG)
  4044.     lea    DISP(HEAP_REG,SCM_type_SUBTYPED),ATEMP1
  4045.     movl    ATEMP1,PVM1_REG
  4046.  
  4047. /* check heap overflow */
  4048.  
  4049.     CMPL(    DISP(PSTATE_REG,SLOT(HEAP_LIM)),HEAP_REG)
  4050.     BCCS(    ok)
  4051.     movl    PVM0_REG,PDEC(SP)
  4052.     TRAP(heap_alloc1_trap,alloc1,1,1)
  4053.     movl    PINC(SP),PVM0_REG
  4054. LBL(ok):
  4055.  
  4056.     jmp    IND(PVM0_REG)
  4057.  
  4058. CONSTS(0)
  4059. END
  4060.  
  4061. /*---------------------------------------------------------------------------*/
  4062.  
  4063. #undef LBL
  4064. #define LBL(x)MAKE_LBL(57,x)
  4065.  
  4066. BEGIN("##semaphore-wait")
  4067.  
  4068.     BMIS(    passed_1arg)
  4069.  
  4070.     WRONG_NB_ARGS(wrong_nb_arg1_trap,1,$entry)
  4071.  
  4072. LBL(passed_1arg):
  4073.  
  4074.     movl    PVM1_REG,PVM4_REG
  4075.  
  4076.     movl    PVM4_REG,ATEMP2
  4077.     lea    DISP(ATEMP2,SLOT(SEMAPHORE_COUNT)+4-SCM_type_SUBTYPED),ATEMP2
  4078.  
  4079.     movl    PVM0_REG,PVM3_REG
  4080.     LOCK_ATEMP2(lock1)
  4081.     movl    PVM3_REG,PVM0_REG
  4082.  
  4083.     clrl    IND(ATEMP2)        /* semaphore count now 0 */
  4084.  
  4085.     tstl    DTEMP1            /* semaphore count was 0? */
  4086.     BEQS(    count_was_0)
  4087.  
  4088.     movl    FALSE_REG,PVM1_REG
  4089.     jmp    IND(PVM0_REG)
  4090.  
  4091. LBL(count_was_0):
  4092.  
  4093. /* suspend task on semaphore */
  4094.  
  4095.     movl    PVM0_REG,PDEC(SP)
  4096.  
  4097. /* Call ###_kernel.transfer-lazy-tasks-to-heap. */
  4098.  
  4099.     pea    PC_IND(ret1)
  4100.     movl    CONST(0),ATEMP1
  4101.     jmp    IND(ATEMP1)
  4102. RETURN(ret1,1,1):
  4103.  
  4104. /* Call ###_kernel.transfer-stack-to-heap. */
  4105.  
  4106. /* ###_kernel.transfer-lazy-tasks-to-heap has reserved enough */
  4107. /* space, so no GC check required.                            */
  4108.  
  4109.     pea    PC_IND(ret2)
  4110.     movl    CONST(1),ATEMP1
  4111.     jmp    IND(ATEMP1)
  4112. LBL(ret2):
  4113.  
  4114. /* Save state of current task. */
  4115.  
  4116.     movl    DISP(PSTATE_REG,SLOT(CURRENT_TASK)),ATEMP1
  4117.  
  4118.     movl    PINC(SP),PVM0_REG
  4119.     movl    PVM0_REG,DISP(ATEMP1,SLOT(TASK_CONT_RET)+4-SCM_type_SUBTYPED)
  4120.     movl    PVM2_REG,DISP(ATEMP1,SLOT(TASK_CONT_FRAME)+4-SCM_type_SUBTYPED)
  4121.     movl    DISP(PSTATE_REG,SLOT(CURRENT_DYN_ENV)),DISP(ATEMP1,SLOT(TASK_CONT_DYN_ENV)+4-SCM_type_SUBTYPED)
  4122.     movl    FALSE_REG,DISP(ATEMP1,SLOT(TASK_VALUE)+4-SCM_type_SUBTYPED)
  4123.  
  4124.     movl    ATEMP1,PDEC(HEAP_REG)
  4125.     movl    HEAP_REG,PVM3_REG
  4126.     movl    NULL_REG,PDEC(HEAP_REG)
  4127.  
  4128. /* Final check for availability. */
  4129.  
  4130.     movl    PVM4_REG,ATEMP2
  4131.     lea    DISP(ATEMP2,SLOT(SEMAPHORE_COUNT)+4-SCM_type_SUBTYPED),ATEMP2
  4132.  
  4133.     LOCK_ATEMP2(lock2)
  4134.  
  4135.     tstl    DTEMP1            /* semaphore count was 0? */
  4136.     BEQS(    semaphore_still_not_free)
  4137.  
  4138.     clrl    IND(ATEMP2)        /* semaphore count now 0 */
  4139.  
  4140.     addql    IMM(8),HEAP_REG        /* discard cons cell */
  4141.  
  4142. /* Resume task. */
  4143.  
  4144.     movl    DISP(PSTATE_REG,SLOT(CURRENT_TASK)),ATEMP2
  4145.     movl    DISP(ATEMP2,SLOT(TASK_CONT_RET)+4-SCM_type_SUBTYPED),DISP(PSTATE_REG,SLOT(PARENT_RET))
  4146.     movl    DISP(ATEMP2,SLOT(TASK_CONT_FRAME)+4-SCM_type_SUBTYPED),DISP(PSTATE_REG,SLOT(PARENT_FRAME))
  4147.     movl    DISP(ATEMP2,SLOT(TASK_CONT_DYN_ENV)+4-SCM_type_SUBTYPED),DISP(PSTATE_REG,SLOT(CURRENT_DYN_ENV))
  4148.  
  4149.     movl    PVM4_REG,PVM0_REG
  4150.     movl    PVM4_REG,PVM1_REG
  4151.     movl    PVM4_REG,PVM2_REG
  4152.     movl    PVM4_REG,PVM3_REG
  4153.  
  4154.     movl    DISP(PSTATE_REG,SLOT(BOS_RET)),ATEMP1
  4155.     jmp    IND(ATEMP1)
  4156.  
  4157. LBL(semaphore_still_not_free):
  4158.  
  4159. #ifndef butterfly
  4160.  
  4161.     CMPL(    DISP(PSTATE_REG,SLOT(WORKQ_TAIL)),NULL_REG)    /* anything else runnable? */
  4162.     BNES(    no_deadlock)
  4163.  
  4164. /* Resume task. */
  4165.  
  4166.     movl    DISP(PSTATE_REG,SLOT(CURRENT_TASK)),ATEMP2
  4167.     movl    DISP(ATEMP2,SLOT(TASK_CONT_RET)+4-SCM_type_SUBTYPED),DISP(PSTATE_REG,SLOT(PARENT_RET))
  4168.     movl    DISP(ATEMP2,SLOT(TASK_CONT_FRAME)+4-SCM_type_SUBTYPED),DISP(PSTATE_REG,SLOT(PARENT_FRAME))
  4169.     movl    DISP(ATEMP2,SLOT(TASK_CONT_DYN_ENV)+4-SCM_type_SUBTYPED),DISP(PSTATE_REG,SLOT(CURRENT_DYN_ENV))
  4170.  
  4171.     movl    PVM4_REG,PVM0_REG
  4172.     movl    PVM4_REG,PVM1_REG
  4173.     movl    PVM4_REG,PVM2_REG
  4174.     movl    PVM4_REG,PVM3_REG
  4175.  
  4176.     movl    DISP(PSTATE_REG,SLOT(BOS_RET)),PVM0_REG
  4177.     movl    CONST(3),ATEMP1    /* jump to ##exception.deadlock */
  4178.     moveq    IMM(1),DTEMP1    /* passing 0 argument */
  4179.     jmp    IND(ATEMP1)
  4180.  
  4181. LBL(no_deadlock):
  4182.  
  4183. #endif
  4184.  
  4185. /* add task to tail of waiting queue */
  4186.  
  4187.     movl    DISP(ATEMP2,SLOT(SEMAPHORE_TAIL-SEMAPHORE_COUNT)),DTEMP1
  4188.     CMPL(    DTEMP1,NULL_REG)
  4189.     BEQS(    empty)
  4190.     movl    DTEMP1,ATEMP1
  4191.     movl    PVM3_REG,PDEC(ATEMP1)
  4192.     BRAS(    done)
  4193. LBL(empty):
  4194.     movl    PVM3_REG,DISP(ATEMP2,SLOT(SEMAPHORE_HEAD-SEMAPHORE_COUNT))
  4195. LBL(done):
  4196.     movl    PVM3_REG,DISP(ATEMP2,SLOT(SEMAPHORE_TAIL-SEMAPHORE_COUNT))
  4197.  
  4198.     clrl    IND(ATEMP2)        /* semaphore count now 0 */
  4199.  
  4200. #ifdef MAINTAIN_TASK_STATUS
  4201.  
  4202. /* Change task's status to WAITING */
  4203.  
  4204.     movl    DISP(PSTATE_REG,SLOT(CURRENT_TASK)),ATEMP1
  4205.     movl    NULL_REG,DISP(ATEMP1,SLOT(TASK_STATUS)+4-SCM_type_SUBTYPED)
  4206.  
  4207. #endif
  4208.  
  4209.     moveq    IMM(0),PVM1_REG
  4210.     movl    CONST(2),ATEMP1
  4211.     jmp    IND(ATEMP1)
  4212.  
  4213. CONSTS(4)
  4214. PRIMITIVE("###_kernel.transfer-lazy-tasks-to-heap")
  4215. PRIMITIVE("###_kernel.transfer-stack-to-heap")
  4216. PRIMITIVE("###_kernel.idle")
  4217. PRIMITIVE("##exception.deadlock")
  4218. END
  4219.  
  4220. /*---------------------------------------------------------------------------*/
  4221.  
  4222. #undef LBL
  4223. #define LBL(x)MAKE_LBL(58,x)
  4224.  
  4225. BEGIN("##semaphore-signal")
  4226.  
  4227.     BMIS(    passed_1arg)
  4228.  
  4229.     WRONG_NB_ARGS(wrong_nb_arg1_trap,1,$entry)
  4230.  
  4231. LBL(passed_1arg):
  4232.  
  4233.     movl    PVM1_REG,PVM4_REG
  4234.  
  4235.     movl    PVM4_REG,ATEMP2
  4236.     lea    DISP(ATEMP2,SLOT(SEMAPHORE_COUNT)+4-SCM_type_SUBTYPED),ATEMP2
  4237.  
  4238.     movl    PVM0_REG,PVM3_REG
  4239.     LOCK_ATEMP2(lock1)
  4240.     movl    PVM3_REG,PVM0_REG
  4241.  
  4242.     movl    DISP(ATEMP2,SLOT(SEMAPHORE_TAIL-SEMAPHORE_COUNT)),DTEMP1
  4243.     CMPL(    DTEMP1,NULL_REG)
  4244.     BNES(    restart_task)
  4245.  
  4246.     movl    IMM(1*8),IND(ATEMP2)    /* semaphore count now 1 */
  4247.  
  4248.     movl    FALSE_REG,PVM1_REG
  4249.     jmp    IND(PVM0_REG)
  4250.  
  4251. LBL(restart_task):
  4252.  
  4253. /* remove first task from waiting queue */
  4254.  
  4255.     movl    DISP(ATEMP2,SLOT(SEMAPHORE_HEAD-SEMAPHORE_COUNT)),ATEMP1
  4256.     movl    DISP(ATEMP1,SLOT(-1)),PVM1_REG
  4257.     movl    PVM1_REG,DISP(ATEMP2,SLOT(SEMAPHORE_HEAD-SEMAPHORE_COUNT))
  4258.     CMPL(    PVM1_REG,NULL_REG)
  4259.     BNES(    done)
  4260.     movl    NULL_REG,DISP(ATEMP2,SLOT(SEMAPHORE_TAIL-SEMAPHORE_COUNT))
  4261. LBL(done):
  4262.  
  4263.     clrl    IND(ATEMP2)        /* semaphore count now 0 */
  4264.  
  4265. #ifdef MAINTAIN_TASK_STATUS
  4266.  
  4267. /* Change task's status to READY */
  4268.  
  4269.     movl    IND(ATEMP1),ATEMP2
  4270.     movl    ATEMP1,DISP(ATEMP2,SLOT(TASK_STATUS)+4-SCM_type_SUBTYPED)
  4271.  
  4272. #endif
  4273.  
  4274. /* add task to work queue */
  4275.  
  4276.     movl    FALSE_REG,DISP(PSTATE_REG,SLOT(WORKQ_LOCKO))
  4277. LBL(lock_workq):
  4278.     tstl    DISP(PSTATE_REG,SLOT(WORKQ_LOCKV))
  4279.     BNES(    lock_workq)
  4280.  
  4281.     movl    DISP(PSTATE_REG,SLOT(WORKQ_TAIL)),ATEMP2
  4282.     CMPL(    ATEMP2,NULL_REG)
  4283.     BNES(    non_empty_queue)
  4284.     movl    ATEMP1,DISP(PSTATE_REG,SLOT(WORKQ_HEAD))
  4285.     BRAS(    fix_tail)
  4286. LBL(non_empty_queue):
  4287.     movl    ATEMP1,PDEC(ATEMP2)
  4288.  
  4289. LBL(fix_tail):
  4290.     movl    ATEMP1,DISP(PSTATE_REG,SLOT(WORKQ_TAIL))
  4291.  
  4292.     movl    NULL_REG,PDEC(ATEMP1)
  4293.  
  4294.     clrl    DISP(PSTATE_REG,SLOT(WORKQ_LOCKO))
  4295.  
  4296. /* return */
  4297.  
  4298.     movl    FALSE_REG,PVM1_REG
  4299.     jmp    IND(PVM0_REG)
  4300.  
  4301. CONSTS(0)
  4302. END
  4303.  
  4304. /*---------------------------------------------------------------------------*/
  4305.  
  4306. #undef LBL
  4307. #define LBL(x)MAKE_LBL(59,x)
  4308.  
  4309. BEGIN("##legitimacy-barrier")
  4310.  
  4311.     CMPW(    IMM(1),DTEMP1)
  4312.     BEQS(    passed_0arg)
  4313.  
  4314.     WRONG_NB_ARGS(wrong_nb_arg1_trap,0,$entry)
  4315.  
  4316. LBL(passed_0arg):
  4317.     movl    DISP(PSTATE_REG,SLOT(CURRENT_TASK)),ATEMP1
  4318.     movl    DISP(ATEMP1,SLOT(TASK_LEGIT)+4-SCM_type_SUBTYPED),PVM1_REG
  4319.  
  4320. /* touch legitimacy placeholder */
  4321.  
  4322.     btst    PVM1_REG,PLACEHOLDER_REG
  4323.     BEQS(    touch)
  4324.     jmp    IND(PVM0_REG)
  4325.  
  4326. LBL(touch):
  4327.     movl    PVM1_REG,ATEMP2
  4328.     movl    DISP(ATEMP2,SLOT(PH_VALUE)-SCM_type_PLACEHOLDER),PVM1_REG
  4329.     CMPL(    ATEMP2,PVM1_REG)
  4330.     BNES(    determined)
  4331.  
  4332.     LOG(EVENT_TOUCH_UNDET,log1)
  4333.  
  4334. /* legitimacy placeholders can be determined to placeholders, so must chase */
  4335.  
  4336.     movl    PVM0_REG,PDEC(SP)
  4337.     lea    PC_IND(ret),PVM0_REG
  4338.     movl    CONST(0),ATEMP1
  4339.     jmp    IND(ATEMP1)    /* jump to ###_kernel.touch */
  4340. RETURN(ret,1,1):
  4341.     movl    PINC(SP),PVM0_REG
  4342. LBL(determined):
  4343.     btst    PVM1_REG,PLACEHOLDER_REG
  4344.     BEQS(    touch)
  4345.  
  4346.     jmp    IND(PVM0_REG)
  4347.  
  4348. CONSTS(1)
  4349. PRIMITIVE("###_kernel.touch")
  4350. END
  4351.  
  4352. /*---------------------------------------------------------------------------*/
  4353.  
  4354. #undef LBL
  4355. #define LBL(x)MAKE_LBL(60,x)
  4356.  
  4357. BEGIN("##sequentially")
  4358.  
  4359.     BMIS(    passed_1arg)
  4360.  
  4361.     WRONG_NB_ARGS(wrong_nb_arg1_trap,1,$entry)
  4362.  
  4363. LBL(passed_1arg):
  4364.  
  4365.     movl    PVM0_REG,PDEC(SP)
  4366.  
  4367. /* Call ###_kernel.transfer-lazy-tasks-to-heap. */
  4368.  
  4369.     CMPL(    DISP(PSTATE_REG,SLOT(LTQ_HEAD)),LTQ_TAIL_REG)
  4370.     BEQS(    tasks_transferred)
  4371.  
  4372.     movl    PVM1_REG,PDEC(SP)
  4373.     pea    PC_IND(ret1)
  4374.     movl    CONST(0),ATEMP1
  4375.     jmp    IND(ATEMP1)
  4376. RETURN(ret1,2,1):
  4377.     movl    PINC(SP),PVM1_REG
  4378.     moveq    IMM(0),PVM3_REG
  4379.  
  4380. LBL(tasks_transferred):
  4381.  
  4382.     movl    PVM1_REG,ATEMP2
  4383.  
  4384. /* Remove tasks from workq */
  4385.  
  4386.     movl    FALSE_REG,DISP(PSTATE_REG,SLOT(WORKQ_LOCKO))
  4387. LBL(lock_workq1):
  4388.     tstl    DISP(PSTATE_REG,SLOT(WORKQ_LOCKV))
  4389.     BNES(    lock_workq1)
  4390.  
  4391.     movl    DISP(PSTATE_REG,SLOT(WORKQ_HEAD)),PDEC(SP)
  4392.  
  4393.     movl    NULL_REG,DISP(PSTATE_REG,SLOT(WORKQ_HEAD))
  4394.     movl    NULL_REG,DISP(PSTATE_REG,SLOT(WORKQ_TAIL))
  4395.  
  4396.     clrl    DISP(PSTATE_REG,SLOT(WORKQ_LOCKO))
  4397.  
  4398. /* Call procedure */
  4399.  
  4400.     lea    PC_IND(ret2),PVM0_REG
  4401.     moveq    IMM(1),DTEMP1
  4402.     jmp    IND(ATEMP2)
  4403.  
  4404. RETURN(ret2,2,1):
  4405.  
  4406. /* Restore tasks to workq */
  4407.  
  4408.     movl    PINC(SP),PVM2_REG
  4409.  
  4410.     btst    PVM2_REG,PAIR_REG    /* pair? */
  4411.     BNES(    done)
  4412.  
  4413.     movl    PVM2_REG,DTEMP1        /* get tail */
  4414. LBL(loop):
  4415.     movl    DTEMP1,ATEMP2
  4416.     movl    PDEC(ATEMP2),DTEMP1
  4417.     btst    DTEMP1,PAIR_REG
  4418.     BEQS(    loop)
  4419.  
  4420.     movl    FALSE_REG,DISP(PSTATE_REG,SLOT(WORKQ_LOCKO))
  4421. LBL(lock_workq2):
  4422.     tstl    DISP(PSTATE_REG,SLOT(WORKQ_LOCKV))
  4423.     BNES(    lock_workq2)
  4424.  
  4425.     CMPL(    DISP(PSTATE_REG,SLOT(WORKQ_TAIL)),NULL_REG)
  4426.     BNES(    non_empty_queue)
  4427.     movl    NULL_REG,PINC(ATEMP2)
  4428.     movl    ATEMP2,DISP(PSTATE_REG,SLOT(WORKQ_TAIL))
  4429.     BRAS(    fix_head)
  4430. LBL(non_empty_queue):
  4431.     movl    DISP(PSTATE_REG,SLOT(WORKQ_HEAD)),PINC(ATEMP2)
  4432. LBL(fix_head):
  4433.     movl    PVM2_REG,DISP(PSTATE_REG,SLOT(WORKQ_HEAD))
  4434.  
  4435.     clrl    DISP(PSTATE_REG,SLOT(WORKQ_LOCKO))
  4436.  
  4437. LBL(done):
  4438.     rts
  4439.  
  4440. CONSTS(1)
  4441. PRIMITIVE("###_kernel.transfer-lazy-tasks-to-heap")
  4442. END
  4443.  
  4444. /*---------------------------------------------------------------------------*/
  4445.  
  4446. #undef LBL
  4447. #define LBL(x)MAKE_LBL(61,x)
  4448.  
  4449. BEGIN("###_kernel.startup")
  4450.  
  4451. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  4452.  
  4453. /* Save C's context: */
  4454.  
  4455.     movl    CONST(0),REG(a1)
  4456. #ifndef MIN_C_CONTEXT
  4457.     movl    REG(d2),DISP(REG(a1),C_D2)
  4458.     movl    REG(d3),DISP(REG(a1),C_D3)
  4459.     movl    REG(d4),DISP(REG(a1),C_D4)
  4460.     movl    REG(d5),DISP(REG(a1),C_D5)
  4461.     movl    REG(d6),DISP(REG(a1),C_D6)
  4462.     movl    REG(d7),DISP(REG(a1),C_D7)
  4463.     movl    REG(a2),DISP(REG(a1),C_A2)
  4464.     movl    REG(a3),DISP(REG(a1),C_A3)
  4465.     movl    REG(a4),DISP(REG(a1),C_A4)
  4466. #endif
  4467.     movl    REG(a5),DISP(REG(a1),C_A5)
  4468.     movl    REG(a6),DISP(REG(a1),C_A6)
  4469.     movl    SP,DISP(REG(a1),C_SP)
  4470.  
  4471. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  4472.  
  4473. /* Get parameters: */
  4474.  
  4475.     movl    DISP(SP,4),TABLE_REG    /* always = ptr to glob/code table */
  4476.     movl    DISP(SP,8),PSTATE_REG    /* always = ptr to processor state */
  4477.  
  4478.     movl    DISP(SP,12),DTEMP1    /* init 68881 coprocessor */
  4479.     BEQS(    no_68881)
  4480.     fmovel    IMM(0),FPSR
  4481.     fmovel    IMM(0),FPCR
  4482. LBL(no_68881):
  4483.  
  4484. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  4485.  
  4486. /* Setup registers: */
  4487.  
  4488.     moveq    IMM(0),INTR_TIMER_REG
  4489.  
  4490.     movl    IMM(SCM_null),NULL_REG
  4491.     movl    IMM(SCM_false),FALSE_REG
  4492.  
  4493.     movl    DISP(PSTATE_REG,SLOT(HEAP_PTR)),HEAP_REG
  4494.  
  4495. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  4496.  
  4497. /* Setup stack structure: */
  4498.  
  4499.     movl    DISP(PSTATE_REG,SLOT(STACK_BOT)),DTEMP1
  4500.     addl    IMM(SLOT(STACK_ALLOCATION_FUDGE)),DTEMP1
  4501.     addl    DISP(PSTATE_REG,SLOT(STACK_MARGIN)),DTEMP1
  4502.     movl    DTEMP1,DISP(PSTATE_REG,SLOT(STACK_LIM))
  4503.  
  4504.     movl    IMM(-1),DISP(PSTATE_REG,SLOT(INTR_FLAG))
  4505.  
  4506.     movl    DISP(PSTATE_REG,SLOT(STACK_PTR)),SP
  4507.     movl    DISP(PSTATE_REG,SLOT(LTQ_TAIL)),LTQ_TAIL_REG
  4508.  
  4509. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  4510.  
  4511. /* Setup 'bottom of stack' return address: */
  4512.  
  4513.     lea    PC_IND(bos_ret),PVM0_REG
  4514.     movl    PVM0_REG,DISP(PSTATE_REG,SLOT(BOS_RET))
  4515.  
  4516. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  4517.  
  4518. /* Start processors: */
  4519.  
  4520.     MAKE_TEMP_TASK
  4521.  
  4522.     movl    DISP(PSTATE_REG,SLOT(ID)),DTEMP1
  4523.     BEQS(    processor0)
  4524.  
  4525. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  4526.  
  4527. /* Startup other processors: */
  4528.  
  4529.     moveq    IMM(0),PVM1_REG
  4530.     movl    CONST(1),ATEMP1
  4531.     jmp    IND(ATEMP1)
  4532.  
  4533. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  4534.  
  4535. /* Startup processor 0: */
  4536.  
  4537. LBL(processor0):
  4538.  
  4539. /* Make root task. */
  4540.  
  4541.     clrl    PDEC(HEAP_REG)
  4542.     clrl    PDEC(HEAP_REG)
  4543.     movl    PSTATE_REG,PDEC(HEAP_REG)
  4544.     clrl    PDEC(HEAP_REG)
  4545.     clrl    PDEC(HEAP_REG)
  4546.     movl    IMM(SCM_true),PDEC(HEAP_REG)
  4547.     clrl    PDEC(HEAP_REG)
  4548.     clrl    PDEC(HEAP_REG)
  4549.     clrl    PDEC(HEAP_REG)
  4550.     movl    IMM(TASK_SIZE*0x400+(SCM_subtype_TASK*8)),PDEC(HEAP_REG)
  4551.     lea    DISP(HEAP_REG,SCM_type_SUBTYPED),ATEMP1
  4552.  
  4553.     movl    ATEMP1,DISP(PSTATE_REG,SLOT(CURRENT_TASK))
  4554.  
  4555. /* Make root continuation. */
  4556.  
  4557.     subql    IMM(4),HEAP_REG
  4558.     movl    FALSE_REG,PDEC(HEAP_REG)
  4559.     movl    FALSE_REG,PDEC(HEAP_REG)
  4560.     movl    IMM(2*0x400+SCM_subtype_FRAME*8),PDEC(HEAP_REG)
  4561.     lea    DISP(HEAP_REG,SCM_type_SUBTYPED),ATEMP2
  4562.  
  4563.     lea    PC_IND(root_continuation),ATEMP1
  4564.     movl    ATEMP1,DISP(PSTATE_REG,SLOT(PARENT_RET))
  4565.     movl    ATEMP2,DISP(PSTATE_REG,SLOT(PARENT_FRAME))
  4566.     movl    NULL_REG,DISP(PSTATE_REG,SLOT(CURRENT_DYN_ENV))
  4567.     movl    DISP(PSTATE_REG,SLOT(BOS_RET)),PVM0_REG
  4568.  
  4569. #ifdef debug
  4570. /*****/    pea    PC_IND($entry)
  4571. /*****/    movl    PINC(SP),DISP(PSTATE_REG,SLOT(56))
  4572. /*****/    movl    DISP(PSTATE_REG,SLOT(BOS_RET)),DISP(PSTATE_REG,SLOT(57))
  4573. /*****/    movl    IMM(0),DISP(PSTATE_REG,SLOT(58))
  4574. #endif
  4575.  
  4576. /* Clear PVM registers. */
  4577.  
  4578.     moveq    IMM(0),PVM1_REG
  4579.     movl    PVM1_REG,PVM2_REG
  4580.     movl    PVM1_REG,PVM3_REG
  4581.     movl    PVM1_REG,PVM4_REG
  4582.  
  4583.     LOG(EVENT_WORKING,log1)
  4584.  
  4585.     movl    CONST(2),ATEMP1        /* jump to ##STARTUP proc */
  4586.     moveq    IMM(1),DTEMP1        /* passing 0 argument */
  4587.     jmp    IND(ATEMP1)
  4588.  
  4589. RETURN(root_continuation,1,1):
  4590.     movl    CONST(0),REG(a1)        /* restore C's registers */
  4591. #ifndef MIN_C_CONTEXT
  4592.     movl    DISP(REG(a1),C_D2),REG(d2)
  4593.     movl    DISP(REG(a1),C_D3),REG(d3)
  4594.     movl    DISP(REG(a1),C_D4),REG(d4)
  4595.     movl    DISP(REG(a1),C_D5),REG(d5)
  4596.     movl    DISP(REG(a1),C_D6),REG(d6)
  4597.     movl    DISP(REG(a1),C_D7),REG(d7)
  4598.     movl    DISP(REG(a1),C_A2),REG(a2)
  4599.     movl    DISP(REG(a1),C_A3),REG(a3)
  4600.     movl    DISP(REG(a1),C_A4),REG(a4)
  4601. #endif
  4602.     movl    DISP(REG(a1),C_A5),REG(a5)
  4603.     movl    DISP(REG(a1),C_A6),REG(a6)
  4604.     movl    DISP(REG(a1),C_SP),SP
  4605.  
  4606.     rts
  4607.  
  4608. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  4609.  
  4610. RETURN(bos_ret,0,0):
  4611. /* A fs of 0 is a special return point marker.  Here it indicates the return */
  4612. /* point in the oldest frame in the stack. */
  4613.  
  4614.     movl    PVM0_REG,DISP(PSTATE_REG,SLOT(TEMP1))
  4615.     movl    PVM1_REG,DISP(PSTATE_REG,SLOT(TEMP2))
  4616.  
  4617. #ifndef MESSAGE_PASSING_STEAL
  4618.  
  4619.     movl    FALSE_REG,DISP(PSTATE_REG,SLOT(STEAL_LOCKO))
  4620. LBL(lock_steal):
  4621.     tstl    DISP(PSTATE_REG,SLOT(STEAL_LOCKV))
  4622.     BNES(    lock_steal)
  4623.     movl    DISP(PSTATE_REG,SLOT(LTQ_HEAD)),LTQ_TAIL_REG
  4624.     movl    DISP(PSTATE_REG,SLOT(Q_BOT)),ATEMP1
  4625. LBL(loop1):
  4626.     clrl    PDEC(LTQ_TAIL_REG)
  4627.     CMPL(    ATEMP1,LTQ_TAIL_REG)
  4628.     BNES(    loop1)
  4629. #endif
  4630.  
  4631.     RESET_STACK
  4632.  
  4633. /* After RESET_STACK, ATEMP1 = DEQ_TAIL */
  4634.  
  4635. #ifdef debug
  4636. /*****/    movl    DISP(PSTATE_REG,SLOT(PARENT_FRAME)),PDEC(SP)
  4637. /*****/    movl    DISP(PSTATE_REG,SLOT(PARENT_RET)),PDEC(SP)
  4638. /*****/    movl    DISP(PSTATE_REG,SLOT(56)),PDEC(SP)
  4639. /*****/    movl    DISP(PSTATE_REG,SLOT(57)),PDEC(SP)
  4640. /*****/    movl    DISP(PSTATE_REG,SLOT(58)),PDEC(SP)
  4641. #endif
  4642.  
  4643.     movl    DISP(PSTATE_REG,SLOT(PARENT_FRAME)),PVM0_REG
  4644.  
  4645.     subql    IMM(SCM_type_SUBTYPED),PVM0_REG
  4646.     movl    PINC(PVM0_REG),PVM1_REG
  4647.     lsrl    IMM(8),PVM1_REG
  4648.  
  4649. LBL(wait):
  4650.     movl    PINC(PVM0_REG),DISP(PSTATE_REG,SLOT(PARENT_FRAME))
  4651.     BNES(    copy_frame)
  4652.     subql    IMM(4),PVM0_REG
  4653.     BRAS(    wait)
  4654. LBL(copy_frame):
  4655.  
  4656. /* copy frame */
  4657.  
  4658. #ifdef RESTORE_PARENT_USING_BTRANSFER
  4659.  
  4660. broken...
  4661.  
  4662.     subql    IMM(4),PVM1_REG        /* PVM1_REG = length of frame */
  4663.     subl    PVM1_REG,SP        /* allocate space on stack */
  4664.     movl    SP,DTEMP1
  4665.     BTRANSFER(copy)
  4666.  
  4667. #else
  4668.  
  4669. #ifdef debug
  4670. /*****/    addw    IMM(5*4),SP
  4671. #endif
  4672.  
  4673.     movl    SP,DTEMP1
  4674.     subql    IMM(4),PVM1_REG        /* PVM1_REG = length of frame */
  4675.     subl    PVM1_REG,SP        /* allocate space on stack */
  4676.     movl    SP,ATEMP2
  4677.  
  4678.     lsrl    IMM(2),PVM1_REG
  4679.     subql    IMM(1),PVM1_REG
  4680. LBL(loop3):
  4681.     movl    PINC(PVM0_REG),PINC(ATEMP2)
  4682.     DBRA(    PVM1_REG,loop3)
  4683.  
  4684. #endif
  4685.  
  4686. /* Scan each frame of continuation... */
  4687.  
  4688.     movl    DISP(PSTATE_REG,SLOT(PARENT_RET)),PVM0_REG
  4689.     movl    SP,PVM1_REG
  4690.  
  4691. #ifdef debug
  4692. /*****/    movl    DISP(PSTATE_REG,SLOT(PARENT_FRAME)),PDEC(SP)
  4693. /*****/    movl    DISP(PSTATE_REG,SLOT(PARENT_RET)),PDEC(SP)
  4694. /*****/    movl    DISP(PSTATE_REG,SLOT(56)),PDEC(SP)
  4695. /*****/    movl    DISP(PSTATE_REG,SLOT(57)),PDEC(SP)
  4696. /*****/    movl    DISP(PSTATE_REG,SLOT(58)),PDEC(SP)
  4697. #endif
  4698.  
  4699.  
  4700. LBL(loop4):
  4701.     movl    PVM1_REG,ATEMP2
  4702.     moveq    IMM(0),PVM1_REG
  4703.     movw    DISP(PVM0_REG,-6),PVM1_REG    /* get fs */
  4704.     BGTS(    normal_ret)
  4705.     BEQS(    dyn_env_ret)
  4706.     movl    ATEMP2,PINC(LTQ_TAIL_REG)    /* push task marker */
  4707.     andw    IMM(0x7fff),PVM1_REG
  4708.     BRAS(    normal_ret)
  4709. LBL(dyn_env_ret):
  4710.     movl    ATEMP2,PDEC(ATEMP1)        /* push dyn env marker */
  4711.     movw    IMM(SLOT(DYN_ENV_FS)),PVM1_REG
  4712. LBL(normal_ret):
  4713.     addl    ATEMP2,PVM1_REG
  4714.     addw    DISP(PVM0_REG,-4),ATEMP2    /* add link */
  4715.     movl    IND(ATEMP2),PVM0_REG
  4716.     CMPL(    DTEMP1,PVM1_REG)
  4717.     BNES(    loop4)
  4718.  
  4719.     movl    DISP(PSTATE_REG,SLOT(BOS_RET)),IND(ATEMP2)
  4720.  
  4721. /* Slots of LTQ and DEQ are in reverse order, so reverse them... */
  4722.  
  4723.     movl    ATEMP1,DISP(PSTATE_REG,SLOT(DEQ_TAIL))
  4724.     movl    DISP(PSTATE_REG,SLOT(DEQ_HEAD)),ATEMP2
  4725. LBL(loop5):
  4726.     movl    PDEC(ATEMP2),DTEMP1
  4727.     CMPL(    ATEMP2,ATEMP1)
  4728.     BCCS(    deq_reversed)
  4729.     movl    IND(ATEMP1),IND(ATEMP2)
  4730.     movl    DTEMP1,PINC(ATEMP1)
  4731.     BRAS(    loop5)
  4732. LBL(deq_reversed):
  4733.  
  4734.     movl    LTQ_TAIL_REG,ATEMP1
  4735.     movl    DISP(PSTATE_REG,SLOT(LTQ_HEAD)),ATEMP2
  4736. LBL(loop6):
  4737.     movl    PDEC(ATEMP1),DTEMP1
  4738.     CMPL(    ATEMP1,ATEMP2)
  4739.     BCCS(    ltq_reversed)
  4740.     movl    IND(ATEMP2),IND(ATEMP1)
  4741.     movl    DTEMP1,PINC(ATEMP2)
  4742.     BRAS(    loop6)
  4743. LBL(ltq_reversed):
  4744.  
  4745. /* Setup correct return address for parent and return to restored cont */
  4746.  
  4747.     movl    DISP(PSTATE_REG,SLOT(PARENT_RET)),ATEMP2
  4748.     movl    PVM0_REG,DISP(PSTATE_REG,SLOT(PARENT_RET))
  4749.  
  4750. #ifndef MESSAGE_PASSING_STEAL
  4751.     clrl    DISP(PSTATE_REG,SLOT(STEAL_LOCKO))
  4752. #endif
  4753.  
  4754. #ifdef debug
  4755. /*****/    addw    IMM(5*4),SP
  4756. /*****/    pea    PC_IND($entry)
  4757. /*****/    movl    PINC(SP),DISP(PSTATE_REG,SLOT(56))
  4758. /*****/    movl    ATEMP2,DISP(PSTATE_REG,SLOT(57))
  4759. /*****/    movl    IMM(0),DISP(PSTATE_REG,SLOT(58))
  4760. #endif
  4761.  
  4762.     movl    DISP(PSTATE_REG,SLOT(TEMP1)),PVM0_REG
  4763.     movl    DISP(PSTATE_REG,SLOT(TEMP2)),PVM1_REG
  4764.  
  4765.     movl    PVM1_REG,DTEMP1 /* Required for the case of a return from a touch of d0 */
  4766.  
  4767.     jmp    IND(ATEMP2)
  4768.  
  4769. CONSTS(3)
  4770. PRIMITIVE("###_kernel")
  4771. PRIMITIVE("###_kernel.idle")
  4772. PRIMITIVE("##startup")
  4773. END
  4774.  
  4775. /*---------------------------------------------------------------------------*/
  4776.  
  4777. OBJECT_FILE_END
  4778.